为什么hash%length 和hashlength-1 的值是一样的(当length=2的幂次方)
当 length 是 2 的幂次方时,hash % length 和 hash & (length - 1) 确实等价,这是计算机科学中一个巧妙的位运算优化。下面通过 4 个关键点彻底解释这个原理:
1. 数学本质(核心原理)
当 length = 2ⁿ 时:
-  length - 1的二进制形式是 全1的比特位
 例如:length = 16 (2⁴)→length - 1 = 15→ 二进制1111
-  hash & (length - 1)相当于 保留hash的低n位,其他位归零
 这本质上就是hash % length的余数
2. 实例演示
假设 length = 8(2³):
length     = 8 = 00001000
length - 1 = 7 = 00000111  // 低3位全1
hash = 21  → 二进制 00010101
21 % 8 = 5
21 & 7 = 00010101 
        & 00000111
        ---------
          00000101 = 5  // 结果相同3. 为什么等价?
-  取模运算: hash % length求的是hash除以length的余数
-  位与运算:当 length是2的幂次方时,length - 1的二进制形式是00...011...1(低位全1)
 hash & (length - 1)相当于:-  保留 hash的低log₂(length)位
-  丢弃高位(正好是 length的整数倍部分)
 
-  
4. 优势对比
| 运算 | 性能 | 适用场景 | 注意事项 | 
|---|---|---|---|
| hash % length | 较慢 | 任意length | 负数需额外处理( Math.abs) | 
| hash & (length-1) | 极快 | length必须为2的幂次方 | 自动处理负数(直接截取低位) | 
关键结论
-  等价条件:仅当 length是 2 的幂次方时成立
-  性能差异:位运算比取模快 5-10 倍(CPU指令级优化) 
-  HashMap的设计: 
 JDK 中HashMap强制容量为2的幂次方(通过tableSizeFor()方法保证),就是为了使用这个优化技巧
为什么HashMap要用这个技巧?
-  极致性能:位运算是CPU原生支持的最快操作之一 
-  避免负数问题: &运算天然处理负数的hash值(而%需要额外处理)
-  与扩容机制完美配合: 
 扩容时只需newIndex = oldIndex | newCapacity(不需要重新计算hash)
理解这个原理,就掌握了HashMap性能优化的第一个关键设计!
