ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

HashMap源码学习和总结

2022-07-18 11:07:47  阅读:185  来源: 互联网

标签:总结 右移 hash HashMap 16 二进制 源码 key 0000


如何计算key的hash值

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

计算hashCode()后的h与h逻辑右移16位的结果异或作为hash值

>>>:无符号右移,将h的二进制数整体右移16位,超出的去掉,左侧空位用0补齐(int型是4字节32位)

举例:

key="java" 

h = key.hashCode() :3254818

二进制:11 0001 1010 1010 0010 0010 (22位,不足32位)

补齐完整的32位:0000 0000 0011 0001 1010 1010 0010 0010     ------ (1)

h>>>16:0000 0000 0000 0000 0000 0000 0011 0001                  -------(2)

^ :对(1)和(2)异或操作,相同为0,不相同为1,可以理解为不进位相加,结果为0000 0000 0011 0001 1010 1010 0001 0011

问题:为什么要设计 右移16位再异或的算法

右移16位后,可以让h的低16位和高16位都参与运算,这样计算出来的最终的hash值更"散",更散意味着更小的hash碰撞,更低的hash冲突

问题:异或(^)相比&,| 有什么优势?

& 很明显,只有1 & 1的结果才是1,其他都是0,这样计算二进制结果肯定都向0 聚集

| 也很明显,只要有1参与运算,结果都是1,只有0|0才是0,这样计算的二进制结果都会向1聚集

^ 不考虑2个二进制的先后位置,如果是0,说明2个位都是0或1,如果是1,说明两个分别是0和1,至于是谁的无所谓

如何计算新key-value落在数组的哪个下标位置

i = (n - 1) & hash

这个结果实际就是hash%n   (n是2的x次幂)

为什么不直接用hash%n ?因为取模运算的效率远低于&运算

为什么每次数组扩容后长度设计为2的N次幂 ?因为设计为2的N次幂,才能使得(n-1)& h 与h%n相等,才能用 按位与 代替 % 运算,提高效率

计算推导:

先举一个例子

100 / 8 = 12
100 % 8 = 4
使用二进制位运算,除以8[2 ^ 3]就是向右移了3位
0110 0100 >> 3 = 0000 1100[100]
0000 1100 = 12 就是商
100 = 4 就是余数
也就是0110 0100的后3位:100

假设n=2 ^ m,除以2 ^ m就是右移m位,得到的结果就是商,移出来的m位二进制转10进制,就是余数(模)

问题转化为:需要将商对应的位全部忽略掉,而余数对应的位数全部保留下来

应该想到h & (00000111) ,就是说h需要和这样的二进制做运算:先是连续的0,后是连续的1,假设有K个连续的1

根据数学里的等比数列通项公式,计算结果为1*2^0+1*2^1+1*2^2+........+1*2^(k-1)=2^k-1

也就是说h要和2^k-1这样的数做&运算,这样的数二进制是 00...011...1,连续的0和连续的1的形式

如果N是2^k,这个设计就OK了,因此,数组的长度扩容时总是为2的N次幂

 

标签:总结,右移,hash,HashMap,16,二进制,源码,key,0000
来源: https://www.cnblogs.com/yb38156/p/16489324.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有