hashmap初始容量仅在构造时确定且不可更改,所谓“动态调整”实为扩容机制;当元素数超阈值(容量×负载因子)时触发翻倍扩容并重哈希,底层数组长度恒为2的幂以支持位运算索引计算。

HashMap 不会“动态调整初始容量”——初始容量只在构造时确定,之后不会自动回退或重设。所谓“动态调整”,实际指的是扩容(resize),即当元素数量超过阈值时,内部数组自动翻倍并迁移数据。
初始容量是在创建时一次性设定的
你只能在 new HashMap(initialCapacity) 时指定初始容量,之后这个值就固定了。即使后续删掉所有元素,容量也不会缩小。比如:
new HashMap
new HashMap
这是因为 HashMap 要求底层数组长度必须是 2 的幂,以便用 (n - 1) & hash 快速计算索引。构造器内部会调用 roundUpToPowerOf2() 自动对齐。
扩容不是“调整初始容量”,而是容量翻倍
当 put 元素导致 size > threshold(即 capacity × loadFactor)时,触发 resize:
- 新容量 = 原容量 × 2(例如 16 → 32 → 64 → 128…)
- 新阈值 = 新容量 × 负载因子(默认仍为 0.75)
- 所有已有元素重新哈希、分配到新数组中
注意:扩容发生在 插入操作中,不是定时或后台行为;而且一旦扩容,旧容量就彻底失效,不再参与任何逻辑。
怎么“合理设置”初始容量?
目标是让预估元素数 ≤ 初始容量 × 0.75,从而避免首次扩容。常用公式:
- 如果预计存 n 个键值对,推荐 initialCapacity = (int)Math.ceil(n / 0.75)
- 再向上取最近的 2 的幂(但 JDK 已帮你做了,你传 14 就行,它自动变成 16)
- 小规模场景(≤16 个)直接用默认构造即可,没必要显式指定
例如:要放 100 个元素 → 100 / 0.75 ≈ 133.3 → 向上取整为 134 → 最近 2 的幂是 128?不对,128 roundUpToPowerOf2(134) == 256。
什么情况下不该手动设初始容量?
除非你明确知道元素数量且性能敏感,否则不建议硬编码:
- 元素数量波动大或不可预估(如缓存、临时聚合)
- 集合生命周期短、使用次数少
- 代码可读性和维护性比微秒级性能更重要
盲目设过大容量(如直接传 10000)会导致内存浪费;设过小又频繁 resize —— 关键是匹配真实负载,而不是“越大越好”或“越小越省”。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











