一、线性结构
1. ArrayList
底层实现:动态数组(
Object[] elementData
)。核心特性:
默认初始容量为
10
,扩容时容量增长为原来的1.5
倍(int newCapacity = oldCapacity + (oldCapacity >> 1)
)。随机访问快(
O(1)
),插入/删除慢(需移动元素,O(n)
)。非线程安全,可用
Collections.synchronizedList
包装。
2. LinkedList
底层实现:双向链表(
Node<E>
节点,包含前驱、后继指针)。核心特性:
插入/删除快(
O(1)
,但需先遍历到位置,实际为O(n)
)。随机访问慢(需从头遍历,
O(n)
)。实现了
Deque
接口,可作为队列或栈使用。
3. Vector
底层实现:与
ArrayList
类似,但所有方法用synchronized
修饰。缺点:性能差(锁粒度大),已被
CopyOnWriteArrayList
或Collections.synchronizedList
取代。
二、哈希表结构
1. HashMap
底层实现(JDK 8+):
数组 + 链表/红黑树(
Node<K,V>[] table
)。链表长度超过
8
且数组长度 ≥64
时,链表转为红黑树;树节点数 ≤6
时退化为链表。
关键机制:
哈希计算:
(key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16)
(扰动函数减少哈希冲突)。扩容:默认负载因子
0.75
,容量翻倍(newCap = oldCap << 1
),重新哈希(JDK 8 优化:元素位置为原位置或原位置+旧容量)。
非线程安全,多线程下可能死循环(JDK 7 链表头插法导致)。
2. LinkedHashMap
底层实现:继承
HashMap
,通过双向链表维护插入顺序或访问顺序(LRU 实现基础)。用途:实现缓存淘汰策略(覆盖
removeEldestEntry
方法)。
3. ConcurrentHashMap
底层实现(JDK 8+):
分段锁 → 改为
Node
数组 +CAS
+synchronized
(锁单个链表头或树根节点)。支持高并发,读操作无锁。
关键优化:
size()
通过baseCount
和CounterCell[]
分片统计,避免竞争。
三、树形结构
1. TreeMap
底层实现:红黑树(自平衡二叉搜索树)。
特性:
键按自然顺序或
Comparator
排序。插入/删除/查询时间复杂度
O(log n)
。
用途:范围查询(
ceilingKey()
,floorKey()
)。
2. PriorityQueue
底层实现:二叉堆(数组实现,
Object[] queue
)。特性:
堆顶元素为最小(默认小顶堆)或最大(通过
Comparator
定义)。插入(
siftUp
)和删除(siftDown
)时间复杂度O(log n)
。
四、集合结构
1. HashSet
底层实现:基于
HashMap
(所有值映射到同一个PRESENT
对象)。特性:
元素唯一性(依赖
hashCode()
和equals()
)。无序,允许
null
。
2. LinkedHashSet
底层实现:继承
HashSet
,内部使用LinkedHashMap
维护插入顺序。
3. TreeSet
底层实现:基于
TreeMap
,元素按自然顺序或Comparator
排序。
五、队列结构
1. ArrayDeque
底层实现:循环数组(
Object[] elements
)。特性:
双端队列(队头/队尾均可操作)。
比
LinkedList
更高效(内存连续,缓存友好)。
2. BlockingQueue
实现类:
ArrayBlockingQueue
(数组)、LinkedBlockingQueue
(链表)、PriorityBlockingQueue
(堆)。特性:
线程安全,支持阻塞插入/取出(
put()
,take()
)。用于生产者-消费者模型。
六、底层实现原理总结
数据结构 | 底层实现 | 时间复杂度(平均) | 线程安全 |
---|---|---|---|
ArrayList | 动态数组 | 查询 O(1) ,增删 O(n) |
否 |
LinkedList | 双向链表 | 查询 O(n) ,增删 O(1) |
否 |
HashMap | 数组+链表/红黑树 | 增删查 O(1) |
否 |
ConcurrentHashMap | 数组+CAS+同步块 | 增删查 O(1) |
是(分段锁) |
TreeMap | 红黑树 | 增删查 O(log n) |
否 |
PriorityQueue | 二叉堆 | 插入/删除 O(log n) |
否 |
七、关键设计思想
动态扩容:
ArrayList
/HashMap
通过扩容平衡空间与时间。扩容需重新分配内存和复制数据,尽量初始化时预估容量(如
new ArrayList<>(100)
)。
哈希冲突解决:
开放寻址法(如
ThreadLocalMap
) vs 链地址法(如HashMap
)。JDK 8 的
HashMap
通过红黑树优化链表过长问题。
树化与退化:
红黑树保证极端情况下(哈希冲突严重)查询效率仍为
O(log n)
。树化阈值(
8
)基于泊松分布统计,冲突概率极低时避免过度优化。
并发控制:
ConcurrentHashMap
通过CAS
+synchronized
降低锁粒度。CopyOnWriteArrayList
通过写时复制实现读操作无锁。
八、使用场景建议
随机访问多 →
ArrayList
。频繁插入/删除 →
LinkedList
。键值对存储 →
HashMap
(无需排序)或TreeMap
(需排序)。高并发场景 →
ConcurrentHashMap
或CopyOnWriteArrayList
。任务调度 →
PriorityQueue
(如定时任务按时间排序)。
理解底层实现能帮助开发者避免性能陷阱(如 HashMap
未设置初始容量导致频繁扩容),并合理选择数据结构。