码迷,mamicode.com
首页 > 其他好文 > 详细

HashMap

时间:2020-01-04 12:50:36      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:示意图   java   pre   分布   类变量   tno   nta   load   rap   

1.HashMap源码

1.1 类Node代码

    HashMap内部存储的单元是Node,Node类源码如下:

?技术图片?

 

1.2 HashMap数据结构

   HashMap数据结构是由Node数组及每个数组元素都是单向链表组成的,结构如下图:

技术图片?

 

  1.3  HashMap get操作  

  get操作就是根据key找到value值。首先key算出hash值,然后调用getNode方法找到value。

技术图片?

   已知HashMap table长度为n,n为2的m次方,即n=2^m,  然后通过hash算法(n-1)&hash算出下hash的二进制低m位作为table的index值,

  从而索引到Node节点,判断此节点hash值和查找的key的值以及key是否相等,相等的话继续沿着此链表查找,知道查找到满足前两个条件

  返回此Node节点,否则返回空。当节点数超过7个,链表转化为红黑树存储,查询就在此红黑树上进行。

 技术图片?

 

技术图片?

 

1.4 HashMap put操作

   HashMap put操作插入对应的key和value。同样先算出key的hash值,然后调用putVal方法。

?技术图片?

putVal方法,同样首先根据hash(key)&(n-1)取得hash值二进制低m位找到index,这样的散列算法使key比较均匀的分布在各个桶里,找到

index索引到Node节点,如果为空,直接put在此节点,否则判断是否是红黑树,如果是则找到红黑树部分的节点则直接put,否则查找

链表中下一个Node节点的key值和hash等于插入的key和hash值的话直接更新Node节点的value值,否则找到Node节点为NULL的节点,

判断链表个数是否超过阈值7,超过链表转换为红黑树,不超过在链表new 新出的节点,然后判断HashMap的节点数是否大于阈值

(负载因子*table的长度),大于的话resize扩容,否则不扩容。

?技术图片?

put方法示意图如下:

技术图片?

1.5 HashMap resize操作

HashMap resize方法首先计算出新的HashMap的容量newCap和新的threshold newThr。判断旧的map容量oldCap大于0并且大于最大容量,

则newThr设置为整形最大值,如果oldCap小于最大容量,则newCap扩大一倍,newThr也扩大一倍,当oldCap<=0&&oldThr>0更新newThr

等于oldThr,当oldCap<=0&&oldThr<=0时newCap设置为默认值,newThr设置为默认值(负载因子*16),当newThr=0时重新计算newThr的值。

?技术图片?

计算完newCap和newThr后,开始HashMap的重新散列,因为Map的length(oldCap)发生变化,数据分布hash方法(length-1)&hash计算出来的索引值

有可能会变化,所以数据需要重新分布。方法是:先便利table数组,分别对数组元素对应每个链表执行rehash。如果链表只有一个节点,则只用计算

此节点对应的新的下标直接赋值即可,如果对应是红黑树,按照红黑树的逻辑去执行,如果是链表,则遍历每个链表,对应对一个节点重新计算出index,

jdk设计精巧体现在这里:因为hash方法(n-1)&hash,所以对于同一个key值,hash值一样,唯一的不同就是长度n,假设n是2的m次方,HashMap扩容之后

n扩大两倍,m加1,所以(n-1)&hash由之前的二进制取低m位变成了取低m+1位,前m位都是一样的,所以差别是第m+1位和1与计算后的结果,有两种情况

一是0,这种情况和扩容之前的取低m位一样,所以index也是一样,另一种情况是1,这种情况相当于2^m+扩容之前的index,第m+1位数字也可以用oldCap&hash

计算出等于0索引值不变,等于1索引值+2^m。所以链表就相应拆成两部分,一部分是索引等于index,一部分等于index+2^m。

技术图片?
?

技术图片?


PS:初始化长度:

技术图片?

因为Java规定了static final 类型为静态类变量 int 类型。int类型限制了该变量的长度为4个字节共32个二进制位,最高位是符号位。

HashMap

标签:示意图   java   pre   分布   类变量   tno   nta   load   rap   

原文地址:https://www.cnblogs.com/cjn123/p/12148356.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!