HashMap扩容阈值严格等于capacity×loadFactor,初始容量16、负载因子0.75时阈值为12,插入第13个元素后数组长度由16变为32;自定义容量32时阈值为24,第25次put触发扩容至64;链表转树前优先判断扩容条件。

可以通过构造特定容量的 HashMap 并逐个插入元素,观察 size 达到阈值后是否触发扩容(即底层数组长度翻倍),来直接验证扩容阈值逻辑。关键不是“看到 resize 被调用”,而是确认扩容行为与 capacity × loadFactor 的数学关系严格一致。
验证初始容量和默认负载因子的组合阈值
默认初始化的 HashMap 容量为 16,负载因子为 0.75,理论阈值为 12。插入第 13 个元素时应完成扩容,数组长度变为 32。
- 使用反射获取
table字段(类型为Node[]),读取其length - 插入 12 个不同 key 后检查
table.length == 16 - 插入第 13 个 key 后检查
table.length == 32 - 注意:必须在插入后立即检查,因为
put是在插入成功且size > threshold时同步触发resize()
验证自定义初始容量对阈值的影响
显式指定初始容量(如 32)可绕过默认 16 的影响,便于隔离测试。此时阈值 = 32 × 0.75 = 24,第 25 次 put 应导致数组变为 64。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 构造
new HashMap<>(32) - 插入 24 个 key 后断言
table.length == 32 - 插入第 25 个 key 后断言
table.length == 64 - 若使用非 2 的幂(如 20),HashMap 会自动向上取整为 32,需在测试前确认实际初始化容量
验证链表转树前的扩容优先级
JDK 8 规定:当链表长度 ≥ 8 且 数组容量
立即学习“Java免费学习笔记(深入)”;
- 创建
new HashMap<>(8)(初始容量 8,阈值 = 6) - 插入 7 个哈希值相同的 key(例如全用
new Object() { public int hashCode() { return 0; } }) - 此时 size = 7 > threshold(6),触发扩容 → table 长度应变为 16
- 继续插入至链表达 8 个节点,但因容量已为 16(仍
- 直到容量 ≥ 64 后,第 8 个冲突 key 才会触发树化而非扩容
验证 threshold 字段的实时值变化
阈值不是静态计算值,而是一个随扩容动态更新的字段。通过反射读取 threshold 成员变量,能最直接确认其是否等于 newCapacity × loadFactor。
- 初始化后读取
threshold,应为 12(对应容量 16) - 扩容后再次读取,应为 24(对应新容量 32)
- 若手动设置负载因子(如
new HashMap<>(16, 0.5f)),阈值应为 8,插入第 9 个元素时扩容 - 注意:JDK 8 中
threshold在 resize 前已被更新为新阈值,所以应在 resize 后 读取

















