HashMap的hash函数和下标计算

HashMap的hash方法如下

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

对key进行了hashCode运算,得到一个32位的int值h,然后用h 异或 h>>>16位,从下边那张图可以看出右移之后前边n位都为0,那么右移之前的n位也可以忽略了,也就是说h的高16位与低16位进行异或。hashCode方法分布已经够均匀的了,为什么还要这么做?(异或:不同为1,相同为0)

先看下put方法怎么找的数组的下标:

 index = (length - 1) & hash

&运算,相同为1,否则为0.
这个算法相当于取模运算%:hash % length。但是前者会比后者效率高点。
因为HashMap的数组长度默认是2的n次幂
假设length的默认大小为24,二进制表示为
00000000000000000000000000010000
24-1为:
00000000000000000000000000001111
最后用一张图表示:
在这里插入图片描述

由上图可知,计算下标的时候只有hash的低16位参与了运算,所以hashCode得到的int值把高16位和低16位进行了一个异或,等于说计算下标时把hash的高16位也参与进来了,减少了hash碰撞。

附:
异或:不同为1,相同为0
&运算,相同为1,否则为0
2的n次幂用二进制表示:

在这里插入图片描述

发布了39 篇原创文章 · 获赞 3 · 访问量 3351

猜你喜欢

转载自blog.csdn.net/administratorJWT/article/details/101295882