理解使用位操作(& 运算)代替求余操作
JDK 8 中,HashMap使用了下面的位运算优化技巧:
当数组长度
length是 2 的整数次幂(即length = 2ⁿ),那么:
hash & (length - 1)=hash % length即:按位与运算的结果,等于取模运算的结果。
为什么成立?
令length = 2ⁿ,例如:
n = 3→length = 8n = 4→length = 16n = 5→length = 32
那么:
length = 2ⁿ = 100...000 (二进制,1 后面 n 个 0)
length - 1 = 2ⁿ-1 = 011...111 (二进制,n 个 1)
举例:
| length | 二进制 | length - 1 | 二进制 |
|---|---|---|---|
| 8 | 1000 |
7 | 0111 |
| 16 | 10000 |
15 | 01111 |
| 32 | 100000 |
31 | 011111 |
可以看到:length - 1的二进制是低 n 位全为 1,高位全为 0。
对任意整数hash,执行hash & (length - 1),相当于只保留hash的低 n 位,高位全部清零。
而hash % length(即hash % 2ⁿ)在数学上也等于hash的低 n 位所代表的数值。因为hash总能够拆分为高位 + 低 n 位,其中高位大于2ⁿ且能够被2ⁿ整除,剩下的低 n 位无法被整除:
![]() |
举例:length = 8(即 n = 3,length - 1 = 7 = 0b111)
| hash (十进制) | hash (二进制) | hash & 7 | hash % 8 |
|---|---|---|---|
| 5 | 0101 |
0101 = 5 |
5 |
| 10 | 1010 |
0010 = 2 |
2 |
| 15 | 1111 |
0111 = 7 |
7 |
| 20 | 10100 |
0100 = 4 |
4 |
结果完全一致。

浙公网安备 33010602011771号