集合框架核心知识
写 Java 代码离不开集合——List、Map、Set 是每天都要打交道的工具。但很多人停留在"会用"层面,不知道:
- ArrayList 的默认容量到底是多少?扩容倍数是多少?
- HashMap 的容量为什么必须是 2 的幂次?
- ConcurrentHashMap 怎么做到高效并发的?
- HashMap 的树化阈值为什么是 8 而不是 16?
这些问题在面试中被追问到的频率极高。我自己也踩过坑——有一次线上服务 GC 频繁,最后排查发现是循环中往 HashMap 插入 40 万条数据,每次都触发扩容,重新 hash 了 18 次。
这套内容,就是帮你把这些集合"从源码层面彻底搞明白"。
内容总览
Java 集合框架是 JDK 中设计最精妙的模块之一。HashMap 的哈希算法、ConcurrentHashMap 的无锁设计、红黑树的阈值选择——每一处设计背后都有深意。
知识全景
ArrayList — 最常用的动态数组 🔴
ArrayList 的默认容量不是 16,是 0。第一次 add 时才扩容到 10。这是 JDK 设计者做的一个优化——避免大多数场景下不必要的内存预分配。
扩容公式:newCapacity = oldCapacity + (oldCapacity >> 1),即 1.5 倍扩容。为什么不是 2 倍?空间和时间的一个平衡点。
循环中往 ArrayList 添加大量元素时,一定要预设容量:new ArrayList<>(expectedSize)。否则每次 add 都可能触发 resize,时间复杂度从 O(n) 变成 O(n²)。
LinkedList — 双端队列 🟡
LinkedList 是双向链表,add/remove 在已知位置时是 O(1),但 get(i) 需要遍历是 O(n)。
很多人觉得"插入多就该用 LinkedList",但实际上大多数业务场景的瓶颈在于 get() 随机访问,而不是 add/remove。95% 的场景用 ArrayList 更好。
HashMap — 集合框架的核心 🔴
HashMap 是 Java 面试中权重最高的集合知识点,没有之一。
HashMap 源码深度解析 — put 流程、哈希算法、树化逻辑
HashMap 扩容机制 — JDK8 优化、e.hash & oldCap 原理
HashMap 红黑树化阈值设计 — 为什么是 8、泊松分布证明
HashMap 的核心设计要点:
- 容量必须是 2 的幂次:
index = (n-1) & hash,因为(n-1)二进制全是 1,&代替% hash()方法:(h = key.hashCode()) ^ (h >>> 16),把高位信息混入低位,减少碰撞- JDK8 引入红黑树:链表过长时退化为 O(n),树化为 O(log n)
- 树化阈值 8:泊松分布计算表明,在负载因子 0.75 下链表长度达到 8 的概率极低
JDK7 的扩容在并发场景下会导致死循环(两个线程同时 resize 时形成环形链表)。JDK8 用 e.hash & oldCap == 0 代替重新 hash,避免了这个问题。
ConcurrentHashMap — 高并发神器 🔴
ConcurrentHashMap JDK7 vs JDK8
ConcurrentHashMap 是并发编程中最常用的线程安全 Map:
- JDK7:Segment 数组,每个 Segment 是一把 ReentrantLock,并发度 = 16
- JDK8:去掉 Segment,改用 Node + CAS + synchronized,只锁单个桶
- JDK8 不允许 null key/value(防止二义性)
LinkedHashMap — 有序 Map 🟡
LinkedHashMap 继承 HashMap,在每个节点上维护 before/after 指针,形成双向链表。设置 accessOrder=true 后,每次 access 都会移动到链表末尾——这就是 LRU 缓存的实现基础。
TreeMap — 有序 Map 🟡
TreeMap 用红黑树实现,key 必须可排序(自然顺序或 Comparator)。它的优势在于:O(log n) 的增删改查 + 有序遍历 + 范围查询(subMap)。
HashSet — Map 的委托 🟡
HashSet 内部就是一个 HashMap,所有元素作为 key,value = 固定的 PRESENT 哨兵对象。HashMap 的 key 唯一性天然实现了 Set 的元素唯一性。
集合对比全景 🟡
HashMap vs Hashtable vs ConcurrentHashMap
选型建议:
- 单线程 + 需要快速随机访问 →
ArrayList - 单线程 + 需要有序 →
TreeSet/TreeMap - 单线程 + 无特殊需求 →
HashSet/HashMap - 并发 + 高性能 →
ConcurrentHashMap - 并发 + 有序 →
ConcurrentSkipListMap
面试关联
集合框架不是孤立的知识点:
- HashMap → ConcurrentHashMap、HashSet
- HashMap 哈希算法 → Redis 字典实现
- 红黑树 → MySQL 索引结构 B+ 树
- ArrayList 扩容 → JVM GC 调优
阅读建议
|| 你的阶段 | 推荐顺序 | | --- | --- | | 面试冲刺 | HashMap → ConcurrentHashMap → ArrayList/LinkedList → 选型对比 | | 系统学习 | ArrayList → LinkedList → HashMap → HashMap 扩容 → HashMap 树化 → ConcurrentHashMap → LinkedHashMap → TreeMap | | 查漏补缺 | 直接找对应知识点定向阅读 |
记住:HashMap 是集合框架的灵魂。把它从 put 流程到扩容机制全部搞透,其他集合都是触类旁通。