HashMap源码(二)

hash方法

这一节主要老看看哈希算法,代码如下:

static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

对key做hashCode运算得到h,然后再对h无符号右移16位再与h做异或运算。h无符号右移16位,则结果是高16位全为0。那么和h运算的结果中,高16位取决于h,低16位其实就是h的高16和低16异或的结果。
为了更好的说明,假设
x = (h >>> 16)
y = h ^ x
这里得到的x的低16位,就是h的高16位。
y的低16位其实就是h的低16位和h的高16位运算的结果。

无符号右移16再异或的好处是什么呢?

后续环节还有位运算,但是用低16位进行运算,如果不把hash值的高16位和低16位进行运算,就会导致后面通过hash值找到数组index的时候,只有低16位参与了运算。在hash函数里面,把高16位和低16位异或运算,可以保证,在hash值的低16位里面,可以同时保留高16位和低16位的特征。
定位元素在数组中的index时,同时将高16位和低16位的特征纳入运算,可以降低hash冲突的概率,如果直接用hash值的低16位去运算,可能会导致一定的hash冲突。

哈希冲突

很多key,可能值不同,但是hash值可能是相同的,或者是hash值不同,但是到数组的index相同,那么都会出现hash冲突

总结

无符号右移运算符(>>>)和右移运算符(>>)的主要区别在于负数的计算。前者右移高位补0,后者高位补1,移多少位补多少位。
异或运算相同为0,不同为1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值