十三、集合框架

集合框架

在这里插入图片描述
以前在存储数据时用到的方法有:

  • 变量:局部变量和成员变量
  • 数组:存入多个同类型的数据
  • 类:存入变量和方法,方便调用
  • 对象数组:通过new一个构造方法,可以快速创建多个不同的对象。解决了重复写多个变量来定义。

集合框架解决了数组不可变的问题(集合也是用数组写的方法,当到达一定长度是,增加数组的长度)

  • Collection接口存储一组不唯一,无序的对象

  • List接口存储一组不唯一,有序(插入顺序)的对象

  • Set接口存储一组唯一,无序的对象

  • Mpa接口存储一组键值对象,提供key到value的映射

List接口的实现类

ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高。

LinkedList采用链表存储方式。插入、删除元素时效率比较高

ArrayList常用方法

ArrayList<存储的数据的类型> 集合名 = new ArrayList<存储的数据的类型>();

  1. boolean add(Object object); 向列表中追加元素
  2. void add(int index,Object object); 向列表中的指定索引添加元素
  3. int size(); 获取列表的长度/元素个数
  4. Object get(int index); 根据索引获取对应的元素
  5. boolean contains(Object obj); 判断是否包含某个元素
  6. boolean remove(Object obj); 删除指定的元素
  7. Object remove(int index); 根据索引删除元素 且返回被删除的元素值

常用接口还有:

clear(); 清空数组

isEmpty(); 判断是否为空

集合里存只能存对象,存基本数据类型是JVM自动包装。

遍历方法:

for 高级for Iterator
基础 常用 操纵指针

LinkedList特有:

双链式
LinkedList数据结构是链表。

LinkedList linkedList = new LinkedList<>();

List接口中的API它也可以使用

  1. void addFirst(Object obj); 将元素添加到集合中第一个
  2. void addLast(Object obj); 将元素添加到集合中的最后一个
  3. Object getFirst(); 获取第一个元素
  4. Object getLast(); 获取最后一个元素
  5. Object removeFirst(); 删除第一个元素
  6. Object removeLast(); 删除最后一个元素

遍历方法:

for 高级for Iterator
基础 常用 操纵指针

Set接口

Set接口存储一组唯一,无序的对象

HashSet是Set接口常用的实现类

Set中存放的是对象的引用

Set接口不存在get()方法

增强型for循环遍历

Iterator遍历

了解ArrayList和LinkedList的区别?(面试题)

ArrayList:底层是数组结构,在遍历或随机查找时比较快;但在添加或删除效率较LinkedList低,因为一个变动,就换导致多个数组的向前或向后移动。

LinkedList:底层是链表结构,链表结构存储每一个元素由两部分组成,数据域和指针域,它没有索引。多个元素之间,双联前后连接。 因为没有索引,所以查找比较慢,因为是链表结构,所以在增加或删除元素,波及的范围小,所以效率相比ArrayList高。

ArrayList的索引是固定的。类似于座位号 。

LinkedList的索引是根据元素位置计算出来的,并非固定的。

Set集合存取数据

特点:无序 唯一

HashSet

它的实现是根据hashCode()和equals()来做的比较。

遍历方法:

高级for Iterator
常用 操纵指针

迭代器Iterator

Iterator(迭代器)模式又称Cursor(游标)模式,用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

// 创建迭代器
Iterator<String> itor = keys.iterator();
// 指针依次查找是否有内容
while(itor.hasNext()) {
    // 返回键内容
    String key = itor.next();
    // 根据键返回值
    String value = countries.get(key);
    System.out.println(key+"-"+value);
}

Map接口

方法写上

看源码

Collections工具

  1. Collections.max(list); // 查找集合中的最大值

  2. Collections.min(list);// 查找集合中的最小值

  3. Collections.sort(list);// 对集合进行升序排序

  4. Collections.reverse(list); // 对集合进行反转

  5. int binarySearch(集合,要查找的元素); 查找指定的键

  6. void shuffle(集合); 打乱集合元素顺序

Comparable()重写

public int compareTo(Object o) {
    Student stu = (Student)o;
    if (this.score == stu.score) {
    return 0;
    }else if(this.score < stu.score){
    return 1;
    }else if(this.score > stu.score) {
    return -1;
    }
    return 0;
}

return 1; 降

return 0;默认降

return -1; 升

Map接口的使用

HashMap<key,value>

Hashtable -> Properties

键是唯一的

常用API

  1. void put(Object key,Object value); 存储键值对
  2. Object get(Object key); 根据键获取值
  3. int size(); 获取集合中的键值对数量
  4. boolean containsKey(Object key); 是否包含指定的键
  5. boolean containsValue(Object value); 是否包含指定的值
  6. Set keySet(); 获取所有键的集合
  7. Collection values(); 获取所有值的集合
  8. Object remove(Object key); 根据键删除值并返回被删除的值
  9. boolean isEmpty(); 判断是否是空集合
  10. void clear(); 清空集合内容

遍历方法:

高级for Iterator 条目
常用 操作指针,先keySet entry

了解HashMap和Hashtable的区别(面试题)

相同点:

  1. HashMap和Hashtable都是Map接口的实现,都可以实现键值对存储。

不同点:

  1. HashMap键值存储都可以为Null,如果键为null则只能存储一次。

    Hashtable键值存储都不允许为Null。

  2. HashMap线程不安全,效率高。

    Hashtable线程安全,效率低。

遍历方法

/**增强for遍历*/
	public void for1(HashMap<String,String> hashMap) {
		Set<String> keySet = hashMap.keySet();
		for (String key : keySet) {
			String value = hashMap.get(key);
			System.out.println(+key+"\t"+value);
		}
	}
	/**迭代器遍历*/
	public void for2(HashMap<String,String> hashMap) {
		Set<String> keySet = hashMap.keySet();
		Iterator<String> itor = keySet.iterator();
		while (itor.hasNext()) {
			String key = itor.next();
			String value = hashMap.get(key);
			System.out.println(+key+"\t"+value);
		}
	}
	/**条目遍历*/
	public void for3(HashMap<String,String> hashMap) {
		Set<Entry<String,String>> entrySet = hashMap.entrySet();
		for (Entry<String,String> entry : entrySet) {
			System.out.println(entry.getKey()+"\t"+entry.getValue());
		}
	}

泛型的基本使用

JDK1.5才出现的

还有包装类、注解、泛型等

  1. 在集合中用泛型声明元素数据类型 泛型必须是引用数据类型(包装类型)且不用强制类型转换

    // 没有泛型要强转且可以添加任意类型
    countries.put("法兰西共和国");
    countries.put(123);
    countries.put(一个对象);
    for (Object obj : set) {
        NewsTitle title = (NewsTitle)obj;
        System.out.println(title.getId()+"-"+title.getTitle());
    }
    // 有就可以不用只能添加指定类型
    countries.put("法兰西共和国");
    countries.put(123); // 检查异常
    for (NewsTitle title : set) {
        System.out.println(title.getId()+"-"+title.getTitle());
    }
    
  2. 利用泛型将程序变得更加易扩展(通过泛型占位符来进行扩展)

    public class Test<T> {
    
        private String field1;
        private String field2;
        // 不确定是什么类型的
        private T field3;
    }
    
    // 接收多个参数,转变为数组
    Arrays.asList(T... a);
    

猜你喜欢

转载自blog.csdn.net/Super_Robot/article/details/89426145