List、Set、Queue、Map
- List:存储的元素是有序的、可重复的。
- Set:存储的元素无序、不可重复的。
- Queue:队列,一种特殊的线性表,先进先出。只允许在表的前端进行删除操作,而在表的后端进行插入。存储的元素是有序的,可重复的。
- Map:使用键值对(key-value)存储,key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值。
一、List集合
1、数组列表ArrayList
- 底层结构为数组Object[],能够快速地进行随机访问和迭代操作。
- 无参构造器初始容量为10,当数组满时,会将其容量增加到原来的 1.5 倍。
- 是非线程安全的,多线程下使用Collections.synchronizedList来包装。
- 在末尾插入或删除元素的时间复杂度为 O(1),在中间插入或删除元素的时间复杂度为 O(n)。
- 与
LinkedList相比,
查找和更新操作的性能更好,但
插入和删除大量元素时性能较差。 - 与数组的区别是没有固定大小的限制,只能存储引用类型数据而不能存储基本类型数据。
- 适用于根据下标位置频繁的随机访问和少量插入、删除操作的场景。
2、双向链表LinkedList
- 底层结构是由Node构成的双向链表,整个链表固定有头节点first和尾节点last。
- 链表中每个Node节点都包含前后指针prev和next,分别指向前后节点。
- 与 ArrayList 相比,增加和删除的操作效率更高,而查找和修改的操作效率较低,同时所需存储空间也更大。
- 没有实现RandomAccess接口,因此LinkedList 不支持随机访问。
- LinkedList在物理上不一定是连续的,在逻辑上是连续的。
- 适用于频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。
3、Vector
- 底层结构为数组Object[],与ArrayList相似。
-
该类中的大部分方法都用了synchronized修饰,是线程安全的支持多线程并发访问。
4、栈Stack
Vector的子类,先进后出(LIFO,Last In First Out)。
二、Set集合
1、哈希表HashSet
- 底层是HashMap结构,其key为存储的元素,value为new Object。
- 集合中元素基于hashCode存储,所以是无序的且不允许有重复元素的,允许存储一个null值。
- 使用哈希表来存储元素,具有高效的插入、删除和查询性能。
- 不是线程安全的,多线程环境可以使用ConcurrentHashSet。
2、链表集合LinkedHashSet
- 继承自
HashSet,
元素的唯一性,具有哈希表的查找性能,无参构造器的初始容量为16。
- 使用链表维护元素的插入顺序,所以其元素是有序的。
- 需要维护链表结构,在添加和删除元素时可能比
HashSet
略慢一些。 LinkedHashSet
是线程不安全的,在多线程环境中可以使用ConcurrentLinkedHashSet。
3、树集合TreeSet
- 底层数据结构为红黑树,无参构造器的初始容量为16。
- 集合中元素无序不可重复,集合元素实现Comparable接口和重写CompareTo方法后可自动排序。
- 红黑树:每个节点要么是红色,要么是黑色;根节点是黑色;每个叶子节点(NIL 节点,空节点)是黑色的,如果一个节点是红色的,则它的两个子节点都是黑色的;从任意节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。
- 红黑树的规则确保了树的平衡,保证了树的高度不会过高,使得查找、插入和删除操作的性能稳定。
4、枚举集合EnumSet
- EnumSet是抽象类,只能通过静态工厂方法构造EnumSet对象,底层是枚举数组Enum[]。
- 存储的所有元素都必须是指定枚举类型的枚举值,不允许加入null元素。
- 内部以位向量的形式存储,这种存储形式非常紧凑、高效,因此EnumSet对象占用内存很小,而且运行效率很好。
三、Queue队列
1、双端队列:ArrayDeque
- 底层为数组Object[],固定有头head和尾tail,不支持存储 null值。
- 可以作为栈(先进后出)来使用,效率高于 Stack;也可以作为队列(先进先出)来使用,效率高于 LinkedList
- 是线程不安全的
2、并发队列PriorityBlockingQueue
- 无界阻塞队列,底层为数组Object[],无参构造器初始容量为11,不支持存储 null值,最大容量是Integer.MAX_VALUE - 8。
- 支持优先级,元素必须实现
Comparable
接口的public int compareTo(T o)
方法。 - 线程安全,通过一个可重入锁ReentrantLock来控制入队和出队操作。
- 父元素的值永远比任何子元素的值还小。最小的值是
queue[0]
3、延迟队列DelayQueue
- 无边界延迟队列,不允许存放null元素
- 底层基于PriorityQueue实现的。该队列中的元素都是按照过期时间顺序排序的,队列头部放的是即将过期的元素。
- 队列中的元素必须实现Delayed接口
- 获取元素时,立即返回,如果没有过期的元素则返回null
四、Map集合
1、HashMap
- 底层为单向链表数组Node[],Node中包含hash值,key,value和next(下一个Node)。
- 根据键的 HashCode 值存储数据,键唯一且无序,具有很快的访问速度。
- 底层的数据结构是数组+链表/红黑树。当发生哈希冲突时,元素会被存储在链表中。如果链表长度大于等于8并且数组长度大于64时,则转换为红黑树。当红黑树节点小于或等于6时,转换为链表。由此达到时间与空间的平衡。
- 无参构造器初始容量为16,最多允许一条键为 null的记录。
- 存储的键值必须为对象数据类型,不能是基本数据类型。
- 当容量达到阈值(默认当前容量的0.75倍)时发生扩容,扩容后容量为原来的两倍,重新哈希原有的键值对,避免哈希冲突。
- 不是线程安全的,多线程环境下可以使用ConcurrentHashMap。
2、LinkedHashMap
- 继承自HashMap具有HashMap的特性,又使用LinkedList维护插入元素的顺序,保证了有序性。
3、HashTable
- 底层为单向链表数组Entry[],Entry中包含hash值,key,value和next(下一个Entry)。
- 键唯一且无序,无参构造器初始容量为11,key、value都不可以为null。
- 是线程安全的,方法都用synchronized修饰。
- 性能比HashMap差。
4、TreeMap
- 有序的key-value集合,通过红黑树实现,底层采用二叉树对元素进行排序。
- 不是线程安全的。
5、EnumMap
- 枚举映射,Key必须是枚举类型,值可以是任意类型。
- 键值对是有序的,其顺序是根据枚举类型中定义的顺序来排序。
- 性能比HashMap要好。
6、ConcurrentHashMap
- 具有与HashMap相同的特性。
- 类中的属性使用volatile修饰,保证了在多线程环境下的可见性和有序性。
- java1.8之后底层采用CAS(Compare-and-Swap)操作结合synchronized同步块保证线程安全。
- CAS是一种无锁化的算法。
- 与HashTable相比,锁的粒度更小,性能也更好。