HashMap的hash方法如何实现的

HashMap通过将key的hashCode进行高位和低位的异或运算来实现扰动计算,从而使得哈希值分布更均匀,减少冲突。例如,未经扰动的连续整数1-7会连续散列,而经过扰动后,它们的散列位置变得更加分散,提高了哈希表的存储效率。
摘要由CSDN通过智能技术生成
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

获取 key 的 hashCode 值,然后将 hashCode 的高 16 位和低 16 位进行异或运算(如果两个数字的对应的二进制位相同,则异或结果的该位为 0;反之为1),这种将高位特性和低位特性结合起来,降低hash冲突概率的方式成为扰动计算;

扰动计算作用:

让 hash 值的分布更加均匀。如果直接使用 key.hashCode(),很可能高位和低位的值都很相近,导致 hash 值分布不均,最终存储位置的分布也不均匀,容易发生冲突

举个例子:

假设我们有这样的输入:1, 2, 3, 4, 5, 6, 7
如果不做扰动计算,直接使用 key.hashCode(),那么 hash 值可能是:

1 -> 1
2 -> 2
3 -> 3
4 -> 4
5 -> 5
6 -> 6
7 -> 7

可以看到,hash 值是连续的 1 到 7,那么它们很可能也连续地散列到表中的位置,例如

索引: 0  1  2  3  4  5  6
值:  1  2  3  4  5  6  7

这会使得 1 和 2,3 和 4 等都映射到相邻的位置,极易发生冲突,hash 分布很不均匀。现在使用 HashMap 的扰动函数进行计算:1 -> 1 ^ (1 >>> 16) = 1 ^ 1 = 0 
2 -> 2 ^ (2 >>> 16) = 2 ^ 0 = 2
3 -> 3 ^ (3 >>> 16) = 3 ^ 0 = 3
4 -> 4 ^ (4 >>> 16) = 4 ^ 0 = 4
5 -> 5 ^ (5 >>> 16) = 5 ^ 0 = 5
6 -> 6 ^ (6 >>> 16) = 6 ^ 0 = 6
7 -> 7 ^ (7 >>> 16) = 7 ^ 0 = 7 可以看到,通过异或运算,1 的 hash 值变成了 0,和其他 hash 值的差距变大了。这时,它们散列到表中的位置会更加分散:索引: 0  3   6   2   5    1   4
值:  0  3   6   2   5    1   4 1 被映射到索引 0,和其他位置的差距变大。所以,通过扰动函数,原本连续的 hash 值 1 到 7,变成了 0, 2, 3, 5, 6这样更加分散的序列。这使得它们可以更加均匀地散列到表中的各个位置,分布也更加均匀

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值