为什么“hash值 & (数组长度-1)”相当于“取模”

29 阅读1分钟

HashMap里,元素的“存储位置”是用“hash值 & (数组长度-1)”算出来的(相当于“取模”,但比%运算快)。

那为什么“hash值 & (数组长度-1)”相当于“取模”呢?

老夫准备了下图,可以看看。

Snipaste_2025-12-29_15-29-52.png

如果数组长度是“2的幂次方”,那么“数组长度-1”的二进制就是“全1”(比如16-1=15→1111),此时“hash & (数组长度-1)”能把hash值的“低位”完全保留,让元素在数组里分布更均匀,减少hash冲突。

为什么这样能减少冲突?因为 hash 值的低位通常是 “随机分布” 的(这是哈希算法的设计目标),全保留低位能让不同数据的 hash 值,转换成数组下标后 “不扎堆”。

那这不是说,高位的差异被忽略了?

你保留了低位,高位呢?

其实在计算hash值时,会把 hashCode 的高16位(前半段)和低16位(后半段)做“异或”(相同为0,不同为1)。

这样,高位的差异就被“带到”低位了,后续压缩时冲突概率更低。

然后再用hash值和数组长度-1进行按位与运算,得到元素应该存储的数组索引。