Java集合
图
集合类是Java数据结构的实现。Java的集合类是java.util包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法

集合

常用单列集合

图

常用多列集合(键值对)

图

  • List:有序、可重复、有索引
  • Set:无序、不可重复、无索引
  • Map:键值对,键不可重复,重复只替换值,值可以重复

Collection接口相关方法

方法 说明
boolean add() 把给定对象添加到集合中
void clear() 清空集合的所有元素
boolean remove() 把给定对象从集合中删除
boolean contains() 判断对象是否包含在集合中
boolean isEmpty() 判断集合是否为空
int size() 返回集合中元素的个数

迭代器

迭代器是集合专用的遍历方式,其类为Iterator

方法 说明
Iterator iterator 迭代器对象,默认指向当前集合的0索引
boolean hashNext() 判断当前元素是否有元素
E next() 获取当前位置的元素,并将迭代器对象移向下一个位置
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String item = iterator.next();
    System.out.println(item);
}

使用迭代器的地方可以使用增强for循环,但是需要注意for循环中的修改不会影响到集合的数据。最后为了代码的简洁,可以使用Lambda进行简化

list.forEach(s -> System.out.println(s));

List

ArrayList

效率高,但线程不安全(没有使用线程同步synchronized修饰相关方法),在多线程的情况下,使用Vector

底层结构:

  • 利用无参构造器创建集合,默认创建长度为0的数组,添加第一个元素时,底层会创建一个长度为10的新数组
  • 使用指定大小的构造器,初始数组容量为指定大小
  • 存满时,会扩容1.5倍
  • 如果一次添加元素过多,1.5倍放不下,则新创建的数组长度以实际为准

底层源码中维护的elementDatatransient关键字修饰,表示该属性不被序列化

LinkedList

LinkedList底层维护的是一个双向链表,对于添加、删除操作效率较高,但是查询效率低,同样线程不安全

ArrayList的比较

集合 底层结构 增删效率 改查效率
ArrayList 可变数组 较低,需要扩容 较高,索引定位
LinkedList 双向链表 较高,链表追加 较低,全部遍历

Vector

ArrayList相似,不同在于:

  • 操作方法都被synchronized修饰,线程同步安全,但效率不如ArrayList
  • 底层扩容机制按2倍

Set

HashSet

底层使用的是HashMap

public HashSet() {
    map = new HashMap<>();
}

对于HashSet在添加一个元素时,会先计算得到hash值并转为索引,如果存储表中该索引位置没有元素,直接加入,有元素则进行equals比较(可重写),相同则放弃,不同则以链表形式加入其后,当链表元素达到8且存储表元素达到64,会自动转为红黑色结构。如果链表元素达到8而存储表元素没有达到64,会进行数组扩容解决(2倍)

LinkedHashSet

LinkedHashSetHashSet的子类,底层是一个LinkedHashMap结构,维护的是数组+双向链表,使用链表来维护元素的顺序,使得元素以插入的顺序保存

TreeSet

无参构造是无序的,使用有参构造器可以传入比较强进行排序,底层是TreeMap

Map

HashMap

HashMap底层为数组加链表结构,默认创建长度为16,加载因子为0.75,即达到12(16 * 0.75)时进行扩容为2倍。当有元素哈希值一样时以链表的形式进行挂载,长度达到8且表中元素达到64进行红黑色的转换,提高性能

HashMap同样线程不安全

HashTable

HashMap相似,HashTable是线程安全的,同时初始容量为11,加载因子0.75(即达到8进行扩容),扩容2倍加1

Properties

继承HashTable,特点与HashTable类似,常用于加载.properties文件场景

方法 说明
Stream filter() 过滤
Stream limit() 获取前几个元素
Stream skip() 跳过前几个元素
Stream distinct() 去重(依赖hashCode和equals方法)
Stream concat() 合并流
Stream map() 转换流中的数据类型
forEach 遍历
count() 统计
toArray() 将流的数据放入数组中
collect() 将流的数据放入集合中