关于hashMap中 计算hashCode的逻辑推理

Posted it馅儿包子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于hashMap中 计算hashCode的逻辑推理相关的知识,希望对你有一定的参考价值。

hashMap中,为了使元素在数组中尽量均匀的分布,所以使用取模的算法来决定元素的位置.如下:

1 //方法一:
2 static final int hash(Object key){//jdk1.8
3   int h;
4   return (key == null) ? 0 : h = key.hashCode() ^ (h >>> 16);
5 }
6 //方法二:
7 static int indexFor(int h,int length){//低版本的源码
8   return h & (length - 1);//第三步,取模运算
9 }

方法一是我当前使用jdk版本的源码,

方法二是在网上查到的低版本的源码,

首先确认:当length总是2的n次方时,  h & (length - 1)   等价于   hash对length取模      ,但是&比%具有更高的效率;(这一点我暂时无法证明).

 

其次,方法一和方法二的原理是一样的,

在JDK1.8的实现中,优化了高位运算的算法,通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16),

主要是从速度、功效、质量来考虑的,这么做可以在数组table的length比较小的时候,也能保证考虑到高低Bit都参与到Hash的计算中,同时不会有太大的开销。

 

 

-----------------------------------

另开头:

为什么数组大小为2的幂时hashmap访问性能最高?

我在网上查了一些博文,好多都”举例说明“,来以事实说话,

其实我感觉这有取巧的嫌疑,

以下为我个人理解:

为什么取length-1(奇数)?  而不是 length-0(偶数)?

在进行&(逻辑与)运算时(例:a & b),只有当 a =true and b =true 时,结果才是 1,否则都是0;

所以,当 hash & 偶数  时,  二进制结果 就总会是偶数,这就导致 数组的偶数位被浪费,数组的奇数位的冲突概率 增高.

 

基于以上,所以  存储位置index = h & (length - 1);   中length取偶数 使得  hashMap具有更高的性能.

 

至于为什么选择 为2的幂?    接触尚短,我暂时还没想到,待后续.

以上是关于关于hashMap中 计算hashCode的逻辑推理的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Java 中计算枚举的哈希码,以及将枚举 hashCodes 组合为 HashMap 的键

关于HashMap自定义key重写hashCode和equals的问题

HashMap的初始长度为啥是16

在java中,关于equals(),和hashCode()的重写问题。

HashSet和HashMap的区别

Java中HashMap的实现原理