欢迎光临
我们一直在努力

HashMap 的容量为什么常用 2 的幂?

因为 2 的幂让 HashMap 能用最低成本的位运算完成分桶,并且让扩容时的旧节点搬迁保持简单。

JDK 17 的 putVal 计算下标时使用:

i = (n – 1) & hash;

容量 n 是 2 的幂时,n – 1 的低位全是 1。这个位与运算保留 hash 的低几位,效果相当于非负 hash 对 n 取模,但不用做除法,而且结果一定落在 [0, n – 1]。Java 的 hashCode() 可以是负数,直接取模可能得到负下标,位与没有这个问题。

扩容到两倍时,旧容量 oldCap 也是 2 的幂。节点只需要判断:

(hash & oldCap) == 0

这位要么是 0,要么是 1。结果是 0,节点留在原下标;结果不是 0,节点移动到“原下标 + oldCap”。这样不必重新计算每个节点的完整取模,也能把旧桶拆成两组。

只用低位会丢掉高位信息,所以 HashMap 还用 h ^ (h >>> 16) 做一次高位扰动。它不是为了制造一个密码学哈希,而是尽力让高位也影响低位分布。

这只是当前 HashMap 的实现取舍。容量是 2 的幂不等于不会碰撞,也不等于所有哈希表都必须这样设计。

赞(0)
未经允许不得转载:171主机测评 » HashMap 的容量为什么常用 2 的幂?
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址