本文档提供了 Java 集合框架 (JCF) 的全面技术概述,JCF 是 Java 中表示和操作集合的统一架构。它侧重于核心集合接口、实现类、底层数据结构、性能特征和常用用法模式。有关 ConcurrentHashMap 等并发集合的信息,请参阅 Java 并发。
Java 集合框架主要围绕两个关键接口组织:Collection 和 Map。 Collection 接口有几个专门的子接口,包括 List、Set 和 Queue。这些接口中的每一个都有具有不同性能特征的多个实现。
来源
Collection 是集合层次结构中的根接口。它用作对象的容器,并表示一组称为元素的对象的集合。它不实现任何具体的数据结构,但为更具体的集合类型提供了基础。
List 接口扩展了 Collection,表示一个有序的元素集合,允许重复值。列表维护插入顺序并允许对元素进行位置访问。
主要实现
ArrayList:基于动态数组LinkedList:实现为双向链表Vector:基于数组的线程安全实现(遗留类)Set 接口扩展了 Collection,表示一个不能包含重复元素的集合。主要实现有
HashSet:基于 HashMap,没有排序保证LinkedHashSet:维护插入顺序,基于 LinkedHashMapTreeSet:按排序顺序维护元素,基于红黑树Queue 表示一个为在处理之前保存元素而设计的集合,通常按 FIFO(先进先出)顺序。
Deque(双端队列)扩展了 Queue,并支持在两端进行插入和删除。
主要实现
PriorityQueue:元素按优先级排序而非 FIFOArrayDeque:实现为可变大小的数组LinkedList:也实现了 DequeMap 并非真正的集合,但包含在集合框架中。它将键映射到值,不允许重复键。主要实现有
HashMap:O(1) 操作,无排序保证LinkedHashMap:维护插入顺序TreeMap:按排序顺序维护键Hashtable:线程安全的遗留实现来源
ArrayList 使用内部的 Object[] 数组来存储元素。当数组填满时,会分配一个更大的新数组,并将所有元素复制过去。这提供了 O(1) 的随机访问,但插入/删除操作可能为 O(n)。
LinkedList 实现为双向链表,其中每个元素都维护着指向前一个和后一个元素的引用。
HashMap 使用桶数组,每个桶包含一个链表或条目的红黑树(Java 8+)。该结构使用哈希码来确定将条目放置在哪个桶中,并处理冲突。
在 Java 8+ 中,当一个桶中的链表超过阈值(通常是 8 个条目)时,它会被转换为红黑树,以将最坏情况的性能从 O(n) 提高到 O(log n)。
HashSet 在内部使用 HashMap 实现,其中元素作为键存储,并带有一个共享的虚拟值。
来源
| 操作 | ArrayList | 链表 |
|---|---|---|
| 访问 | O(1) | O(n) |
| 在末尾插入 | O(1) 摊销 | O(1) |
| 头插 | O(n) | O(1) |
| 按索引插入 | O(n) | O(n) |
| 尾删 | O(1) | O(1) |
| 头删 | O(n) | O(1) |
| 按索引删除 | O(n) | O(n) |
| 搜索 | O(n) | O(n) |
| 操作 | HashMap | TreeMap |
|---|---|---|
| 获取 | O(1) | O(log n) |
| 放置 | O(1) | O(log n) |
| 删除 | O(1) | O(log n) |
| 包含 | O(1) | O(log n) |
| 下一阶段 | O(h/n) | O(log n) |
| 顺序 | 无 | 按键排序 |
来源
ArrayList 是 List 接口的可调整大小的数组实现。它提供常数时间的位置访问,并且对大多数操作都很高效。
主要实现细节
RandomAccess 接口,表示支持快速随机访问来源
HashMap 在假设哈希函数良好的情况下,为基本操作(get 和 put)提供常数时间性能。
主要实现细节
来源
当以下情况时使用 ArrayList
当以下情况时使用 LinkedList
当以下情况时使用 HashMap
当以下情况时使用 TreeMap
当以下情况时使用 LinkedHashMap
来源
JCF 中的大多数集合实现都不是线程安全的。对于并发访问
ConcurrentHashMapCollections.synchronizedXXX 方法使用线程安全的包装器ArrayList 和 HashMap 等标准集合使用快速失败迭代器,如果在迭代期间修改了集合,则会抛出 ConcurrentModificationExceptionConcurrentHashMap 等并发集合使用安全失败迭代器,它们作用于集合的副本,不会抛出异常ensureCapacity 方法isEmpty() 而不是检查 size() == 0LinkedList,因为开销通常会抵消其好处ConcurrentHashMap 而非 Hashtablenull 值来源
来源
Java 集合框架提供了用于存储和操作对象组的全面接口和实现。通过了解每种集合类型的底层数据结构、性能特征和适当的用例,开发人员可以做出明智的决策,以优化其应用程序的性能和可维护性。
选择集合时,请考虑
通过正确的集合选择和恰当的使用模式,Java Collections Framework 可以显著提高代码的可读性、性能和可维护性。
刷新此 Wiki
最后索引时间2025年4月17日(ff77b0)