HashMap中hash()方法的实现原理?
请解释Java 8 HashMap中hash()方法的实现原理:(h = key.hashCode()) ^ (h >>> 16)。说明为什么需要高位扰动,以及这种设计如何减少哈希冲突。
回答
古法程序员
hash()方法源码:
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
什么是高位扰动:
- 将key的hashCode(32位int)的高16位与低16位做**异或(XOR)**运算
- 本质是将高16位的信息混合到低16位中
为什么需要高位扰动:
- 计算桶索引时使用
(n - 1) & hash,如果数组长度n较小(如默认16),参与运算的只有低4位 - 如果两个对象的hashCode在高16位不同、低16位相同,直接使用hashCode会导致它们被映射到同一个桶(冲突)
- 异或后,高位的差异传播到低位,使低位更随机,减少哈希冲突
演示:
hashCode: 0x12345678 = 0001 0010 0011 0100 0101 0110 0111 1000
>>>16: 0x00001234 = 0000 0000 0000 0000 0001 0010 0011 0100
XOR: 0x1234444C = 0001 0010 0011 0100 0100 0100 0100 1100
效果:即使对象的hashCode分布很差(如低16位全为0),扰动后也能获得更好的分布。这是时间(一次位运算)和空间(无需额外数据结构)的最优权衡。