常用的集合有哪些

常用的三大类集合:Set、List、Map。


1 Set

1) Set 集合属于单列集合,不允许包含重复元素;
2) 判断元素是否重复的标准为对象的 equals 方法,存在时返回 false,不存在返回 true;
3) 元素的排序规则,由相应的实现类决定,分为无序、元素大小排序、写入顺序排序;
4) 初始化大小,扩容参考 HashMap。

1.1 Set 接口、实现类:

名称 类型 线程同步 描述
Set 接口 继承了Collection接口
SortedSet 接口 继承了Set接口
HashSet 实现类 不同步 继承了AbstractSet类,实现了Set、Cloneable、Serializable接口
TreeSet 实现类 不同步 继承了AbstractSet类,实现了NavigableSet(继承了SortedSet)、Cloneable、Serializable接口
LinkedHashSet 实现类 不同步 继承了HashSet类,实现了Set、Cloneable、Serializable接口

1.2 HashSet

1) HashSet 实现了 Set 接口,继承了 AbstractSet 类,由哈希表支持,看源码可以发现是一个 HashMap 实例。
2) HashSet 不保证集合内元素的迭代顺序,特别是不保证迭代顺序永久不变,该集合运行 null 元素存在。
3) HashSet 中的元素,作为 HashMap 键值对的 Key 存储,而 Value 由一个统一的值保存。 
4) HashSet 默认初始化大小为 16,扩容加载因子为 0.75,扩容大小为原来的一倍。即一个初始化size为16的
   HashSet,元素添加到12个的时候会进行扩容,扩容后的大小为32。
备注:具体添加、读取、删除等规则需要参考 HashMap 的具体实现。

1.3 TreeSet

1) TreeSet 实现了 NavigableSet 接口,继承了AbstractSet类,由哈希表支持,看源码可以发现是一个 TreeMap 实例。
2) TreeSet 中的元素有序的,排序规则遵照元素本身的大小进行排序,元素不能重复。
3) TreeSet 中的元素,作为 TreeMap 键值对的 Key 存储,而 Value 由一个统一的值保存。 
备注:具体添加、读取、删除等规则需要参考 TreeMap 的具体实现。

1.4 LinkedHashSet

1) LinkedHashSet 实现了 Set 接口,继承了HashSet类,由哈希表支持,看源码可以发现是一个 LinkedHashMap 实例。
2) LinkedHashSet 中的元素有序的,排序规则遵照元素写入顺序进行排序,元素不能重复。
3) LinkedHashSet 中的元素,作为 LinkedHashMap 键值对的 Key 存储,而 Value 由一个统一的值保存。 
备注:具体添加、读取、删除等规则需要参考 LinkedHashMap、HashMap 的具体实现,LinkedHashMap继承了HashMap。

1.5 线程安全

由于 HashSet、TreeSet、LinkedHashSet的底层实现为HashMap、TreeMap、LinkedHashMap,所以Set集合是非线程安全的。
如果要实现 Set 集合的线程安全,可以使用 ConcurrentHashMap 实现一个Set集合。

2 List

1) List 集合属于单列、有序的、允许元素重复、可以为 null 的集合;
2) List 接口的实现类主要有三种:ArrayList、LinkedList、Vector。

2.1 List 接口、实现类:

名称 类型 线程同步 描述
List 接口 继承了Collection接口
ArrayList 实现类 不同步 继承了AbstractList类,实现了List、RandomAccess、Cloneable、Serializable接口
LinkedList 实现类 不同步 继承了AbstractSequentialList类,实现了List、Deque、Cloneable、Serializable接口
Vector 实现类 同步 继承了AbstractList类,实现了List、RandomAccess、Cloneable、Serializable接口

2.2 ArrayList

1) ArrayList 实现了 List 接口,继承了 AbstractList 类,由一个 Object[] 实例实现,即底层为数组结构;
2) 默认初始化长度为 10,扩容规则为 0.5倍的原容量加1,即一次扩容后的长度为 16;
3) 特点:查询速度快,添加、删除相对于LinkedList较慢、线程不同步(不安全)。

2.2 LinkedList

1) LinkedList 实现了 List 接口,继承了 AbstractSequentialList 类,由一个 Node 节点链表实现,即底层为链表结构;
2) 由于LinkedList 数据结构为链表,无预扩容机制;
3) 特点:添加、删除速度快,查询相对于ArrayList较慢、线程不同步(不安全)。

2.3 Vector

1) Vector实现了 List 接口,继承了 AbstractList 类,由一个 Object[] 实例实现,即底层为数组结构;
2) 默认初始化长度为 10,扩容加载因子为 1,当元素长度大于原容量时进行扩容,默认为 10,一次扩容后容量为 20;
3) 特点:线程安全,但是速度慢;在实现的方法上,用 synchronized 关键字进行了修饰,即在方法上实现了同步锁。
备注:具体实现细节请查看源码。

3 Map

1) Map 集合属于双列Key-value键值对的集合,Key不允许重复,是否允许为 null 根据实现类而定,Value 随意;
2) Map 接口的实现类主要有三种:HashMap、LinkedHashMap、TreeMap、Hashtable、ConcurrentHashMap。

3.1 Map 接口、实现类:

名称 类型 线程同步 描述
Map 接口
HashMap 实现类 不同步 继承了AbstractMap类,实现了Map、Cloneable、Serializable接口
LinkedHashMap 实现类 不同步 继承了HashMap类,实现了Map接口
TreeMap 实现类 不同步 继承了AbstractMap类,实现了NavigableMap(继承了SortedMap)、Cloneable、
Serializable接口
Hashtable 实现类 同步 继承了Dictionary类,实现了Map、Cloneable、Serializable接口
ConcurrentHashMap 实现类 同步 继承了AbstractMap类,实现了ConcurrentMap(继承了Map)、Serializable接口

3.2 HashMap

1) HashMap实现了 Map接口,继承了 AbstractMap类,数据结构采用的位桶数组,底层采用链表或红黑树进行存储;
2) 默认初始化长度为 16,扩容加载因子为 0.75,一旦大于 0.75*16之后,就会调用resize()进行扩容,扩容2倍,即32;
3) JDK1.7中,数据结构采用:位桶数组+链表结构;
   JDK1.8中,数据结构采用:位桶数组+(链表/红黑树);
4) 支持克隆,无序,线程不同步,非安全。

3.3 LinkedHashMap

1) LinkedHashMap 实现了 Map 接口,继承了 HashMap 类;
   引用实现;
3) 迭代顺序由 accessOrder 属性的决定,默认为 false,以插入顺序访问;设置为 true 则按上次读取顺序访问(每次访问
   元素时会把元素移动到链表末尾方便下次访问,结构会时刻变化)。
4) 默认初始化长度为 16,扩容加载因子为 0.75,一旦>0.75*16之后,就会调用resize()进行扩容,与HashMap一致;
5) 支持克隆,有序,线程不同步,非安全。

3.4 TreeMap

1) TreeMap实现了 NavigableMap接口,继承了 AbstractMap 类;
2) 数据结构基于红黑树实现;
3) 该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法;
4) 无初始化长度;
5) 支持克隆,有序,线程不同步,非安全。

3.5 Hashtable

1) Hashtable实现了 Map 接口,继承了 Dictionary类;
2) 数据结构:也是一个散列表,数据结构与HashMap相同,key、value都不可以为 null;
3) 该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法;
4) 默认初始化长度为 11,扩容加载因子为 0.75,一旦>0.75*11之后,就会进行扩容,扩容到2n+1,即23;
5) 支持克隆,无序,线程同步,安全。在实现的方法上,用 synchronized 关键字进行了修饰,即在方法上实现了同步锁。
6) 支持 Enumeration 遍历方式。

3.6 ConcurrentHashMap

1) ConcurrentHashMap实现了 ConcurrentMap接口,继承了 AbstractMap类;
2) 默认初始化长度为 16,扩容加载因子为 0.75,一旦大于 0.75*16之后,就会调用resize()进行扩容,扩容2倍,即32;
3) 数据结构:由Segment数组结构和HashEntry数组结构组成,一个ConcurrentHashMap中包含一个Segment数组,
   Segment的结构和HashMap类似,是一种数组和链表结构。
4) 使用了锁分段技术,Segment是一种可重入锁ReentrantLock,每个Segment拥有一个锁,当对HashEntry数组的
   数据进行修改时,必须先获得对应的Segment锁
5) 不支持克隆,无序,线程同步,安全。

猜你喜欢

转载自blog.csdn.net/zhanyufeng888/article/details/82498054