翻倍扩容是hashmap的核心设计,因其能配合位运算实现高效索引重分配并保持容量为2的幂次方;通过hash & (capacity-1)快速计算下标,仅需判断新增高位bit即可完成元素迁移,结合0.75负载因子实现内存与性能的平衡。

因为翻倍扩容能配合位运算实现高效索引重分配,同时保持容量始终为 2 的幂次方,这是 HashMap 哈希寻址机制的核心前提。
哈希索引依赖 2 的幂次方
HashMap 计算数组下标用的是 hash & (capacity - 1) 这个位运算,而不是取模(%)。这个技巧只有在 capacity 是 2 的幂时才等价于取模,且速度更快。比如:
- capacity = 16 → capacity - 1 = 15 → 二进制是 00001111
- capacity = 32 → capacity - 1 = 31 → 二进制是 00011111
如果容量不是 2 的幂(如 10),capacity - 1 = 9(00001001),高位出现 0,会导致部分 hash 位被屏蔽,哈希分布不均、冲突上升。
翻倍让重哈希只需判断一位
扩容从 oldCap → newCap = oldCap × 2,意味着 newCap - 1 比 oldCap - 1 多一个高位的 1。因此,每个元素在新数组中的位置只有两种可能:
- 保持原索引(hash 的新增高位为 0)
- 原索引 + oldCap(hash 的新增高位为 1)
不需要重新计算完整 hash,仅靠检查一个 bit 就能完成拆分——JDK 8 中链表迁移正是利用这一点,避免全量 rehash,大幅提升扩容效率。
负载因子与扩容节奏的平衡
默认负载因子 0.75 是经验值,配合翻倍策略,使得每次扩容后阈值也翻倍(threshold = capacity × 0.75),形成稳定增长节奏:
- 初始:cap=16, thr=12
- 第一次扩容后:cap=32, thr=24
- 第二次扩容后:cap=64, thr=48
这种指数级增长既避免频繁扩容(如每次+1),又防止过度预留空间(如直接设极大值),在内存占用和哈希冲突之间取得实际可用的折中。
本质上,翻倍不是随意选的数字,而是为位运算优化、重哈希简化、以及工程权衡共同决定的设计结果。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











