Java集合框架
Java 集合框架是提供了一套设计优良、易于使用和扩展的接口和类,用于存储和操作一组对象。集合框架位于java.util包中,它提供了丰富的功能来处理数据集合,包括列表( List )、集合( Set )、队列( Queue )、映射( Map )等。
Collection:这是集合层次结构中的根接口。它包含了用于添加、移除和搜索元素的方法。List:继承自Collection接口,是一个有序的集合,允许包含重复元素。支持通过索引来访问元素。- 实现类包括
ArrayList、LinkedList、Vector等。
- 实现类包括
Set:也是一个继承自Collection接口的集合类型,但不允许包含重复元素。- 常见实现类有
HashSet、LinkedHashSet和TreeSet。
- 常见实现类有
Queue:通常用于实现 FIFO (先进先出)的数据结构,但也有其他变种如优先队列。- 优先级队列
PriorityQueue是一个典型的实现。
- 优先级队列
Map:不是Collection接口的子接口,它存储键值对。Map不能包含重复的键;每个键最多只能映射到一个值。- 常见实现类有
HashMap、LinkedHashMap和TreeMap。
- 常见实现类有

Collection接口
Collection接口关系:

List接口实现类介绍
List 表示一个有序的、允许重复元素的集合,并且可以通过索引(位置)来访问和操作其中的元素。
常用方法:
add(E element):在列表末尾添加一个元素。add(int index, E element):在指定索引处插入一个元素。get(int index):返回指定索引处的元素。set(int index, E element):替换指定索引处的元素。remove(int index):删除指定索引处的元素。size():返回列表中的元素个数。indexOf(Object o):返回指定元素首次出现的索引,不存在则返回 -1。lastIndexOf(Object o):返回指定元素最后一次出现的索引。subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 的子列表。
List接口的常见实现类:
ArrayList:基于动态数组实现。更多阅读:ArrayList源码分析。LinkedList:基于双向链表实现。更多阅读:LinkedList源码分析。ArrayList与LinkedList对比如下:
| 特性/类别 | ArrayList | LinkedList |
|---|---|---|
| 数据结构 | 动态数组 | 双向链表 |
| 随机访问性能 | 快(O(1)) | 慢(O(n),需遍历查找) |
| 插入/删除头部 | 慢(O(n),需移动元素) | 快(O(1),只需修改头节点指针) |
| 插入/删除尾部 | 快(O(1),如果无需扩容) | 快(O(1),只需修改尾节点指针) |
| 插入/删除中间 | 慢(O(n),需移动元素) | 较快(O(n),但不涉及元素移动,仅修改指针) |
| 内存占用 | 因为是连续存储,所以内存使用较为紧凑 | 需要额外的空间存储指向前后的引用,内存开销较大 |
| 线程安全性 | 不是线程安全 | 不是线程安全 |
| 实现接口 | List, RandomAccess |
List, Deque |
| 适用场景 | 高效的随机访问,较少的插入和删除操作 | 高效的插入和删除操作,尤其是列表两端 |
Vector(旧类,不建议使用 ):类似于ArrayList,但它是一个同步(线程安全)的集合,它的所有的方法都被隐式地同步了(所有方法 synchronized ),这使得Vector可以在多线程环境中安全使用。然而,由于同步带来的额外开销,使用这个类可能会导致性能下降。通常推荐在单线程环境下使用ArrayList;在多线程并发场景下,使用Collections.synchronizedList(new ArrayList<>());来创建一个线程安全的列表,或者直接使用并发集合如CopyOnWriteArrayList。Stack(旧类,不建议使用 ):扩展了Vector,并实现了后进先出(LIFO, Last In First Out)的数据结构,也是一个同步(线程安全)的集合。它主要用于栈操作。与Vector有同样的性能问题。官方文档推荐使用Deque接口(双端队列)的实现类,如ArrayDeque或LinkedList代替。
Set接口实现类介绍
Set 集合不允许包含重复的元素(判断两个元素是否相同:根据元素的 equals() 方法判断);Set 不能像 List 一样可以通过整数索引来访问元素; Set 不保证元素的顺序,除非使用了特定类型的 Set 实现。
Set接口常用方法:
Set 接口本身提供的方法不多,但因为它继承自 Collection ,所以它可以使用 Collection接口中定义的所有方法,例如:
add(E e):如果Set中尚未包含指定的元素,则将其添加到此集合中。remove(Object o):从此集合中移除指定元素(如果存在)。contains(Object o):如果此集合包含指定的元素,则返回true。size():返回此集合中的元素数量。clear():移除此集合中的所有元素。iterator():返回在此集合中的元素上进行迭代的迭代器。
Set接口的常见实现类:
HashSet- 最常用的
Set实现之一。 - 不保证元素的顺序,且允许
null值。 - 通过哈希表 实现,提供了
O(1)时间性能的基本操作(如添加、删除和查询)。
- 最常用的
LinkedHashSet- 继承自
HashSet,但是通过维护一个双向链表来记住元素插入的顺序。 - 提供了与
HashSet相同的操作效率,并额外支持按插入顺序遍历集合。
- 继承自
TreeSet- 基于红黑树的数据结构,能够对元素进行排序。
- 元素必须实现
Comparable接口,或者在创建TreeSet时提供一个Comparator,以决定元素的排序方式。 - 支持自然排序或定制排序。
EnumSet- 特别为枚举类型设计的高效实现:通过一个位向量( bit vector )来高效地存储和操作枚举类型的元素。
- 必须由同一个枚举类型的所有元素组成。
- 提供了非常快速的操作性能。
Queue接口实现类介绍
Queue 是专门用于表示队列的数据结构,队列通常遵循**先进先出( FIFO, First-In-First-Out )**原则,即最早加入队列的元素将首先被移除。不过,也有例外情况,比如优先级队列,它根据元素的优先级来决定服务顺序。
此外,Java还提供了 Deque (双端队列)接口,允许从两端进行插入和删除操作,适用于栈、队列以及其他需要双向访问的数据结构。
Queue接口常用方法:
add(E e)/offer(E e):向队列尾部添加一个元素。add()方法在插入失败时抛出异常,而offer()返回一个布尔值。remove()/poll():从队列头部移除并返回一个元素。remove()在队列为空时抛出异常,而poll()则返回null。element()/peek():获取但不移除队列头部的元素。element()方法在队列为空时抛出异常,而peek()返回null。
Queue接口的常见实现类:
LinkedList:实现了Queue接口,并且可以作为双端队列使用。它允许在两端进行高效的插入和删除操作。PriorityQueue:基于堆 的数据结构,按照元素的自然顺序或通过提供的Comparator来进行排序。因此,它并不严格遵守FIFO原则,而是根据优先级来确定哪个元素最先出队。
Map接口
Map 接口是集合框架的一部分,但它并不继承自 Collection 接口。 Map 用于存储键值对( key-value pairs ),其中每个键都是唯一的,而值可以重复。通过键可以在 Map 中高效地查找、更新或删除对应的值。
Map接口和类关系:

Map接口常用方法:
- 基本操作:
put(K key, V value):将指定的键值对插入到Map中。get(Object key):根据键返回对应的值。remove(Object key):根据键移除键值对。clear():移除Map中的所有映射关系。isEmpty():检查Map是否为空。size():返回Map中键值对的数量。
- 查询操作:
containsKey(Object key):判断Map是否包含指定的键。containsValue(Object value):判断Map是否包含指定的值。keySet():返回Map中所有键的集合视图。values():返回Map中所有值的集合视图。entrySet():返回Map中所有键值对的集合视图。
Map接口的常见实现类:
HashMap- 最常用的实现之一,基于哈希表实现。
- 允许
null键和null值。 - 不保证顺序。
LinkedHashMap- 继承自
HashMap,但通过维护双向链表来记住元素的插入顺序。 - 可以基于访问顺序进行排序(适合实现LRU缓存)。
- 继承自
TreeMap- 基于红黑树 数据结构,按键的自然顺序或自定义的
Comparator进行排序。 - 不允许
null键。
- 基于红黑树 数据结构,按键的自然顺序或自定义的
Hashtable(旧类,不推荐使用)- 类似于
HashMap,但是是同步的(线程安全),性能较差。 - 不允许
null键和null值。 - 替代类:
ConcurrentHashMap,专门设计用于高并发环境的线程安全HashMap实现,通过分段锁(在 Java 8 前)或数组 + 链表/红黑树(在 Java 8 及以后使用 synchronized 和 CAS )实现高效的并发访问,允许多个线程同时读写而不会导致数据竞争,从而提供高并发场景下的线程安全和性能优化。
- 类似于
EnumMap- 专门用于键为枚举类型的情况(要求所有键必须来自同一个枚举类型),针对枚举类型的键进行了特别优化,提供了更高效的存储和访问速度。