HashMap源码深入解析【中】

HashMap的put方法源码深入分析【中】

在这里插入图片描述
现在要插入元素
if里面是一个扩容的信息,判断条件是(size>=threshold)&&(null!=table[bucketIndex])
注意这个size是整个table数组里面有的Entey的数目,不是数组的长度
现在我们先不看扩容的代码先查看

createEntry(hash,key,value,bucketIndex):

参数:hash值,key,value,数组下标bucketIndex
在这里插入图片描述

这是我之前写的一个思路,和createEntry的思路差不多
put一个Entry时:
在这里插入图片描述
再put一个Entry时
在这里插入图片描述

还以name:list;name2:lisi2为例
Entey<K,V>e=table[bucketIndex];table[bucketIndex]=name:lisi这个name:lisi赋值给e保存下来
然后:table[bucketIndext]=new Entry<>(hash,key,value,e);就是创建一个Entey然后指针指向e,此时table[bucketIndext]=name2:lisi2这个entry
现在我们来讨论扩容的情况:
当满足:判断条件(size>=threshold)&&(null!=table[bucketIndex])时,就要开始扩容:
查看resize(int newCapacity),新的table的长度时原来数组长度的2倍
在这里插入图片描述
查看tansfer(newTable,initHashSeedAsNeeded(newCapacity)):
在这里插入图片描述
for(Entry<K,V> e:table)是遍历数组:
while(null!=e)是遍历链表,我们发现rehash是一个判断条件,这意味着,我们并不是一定要重新哈希,这一点俺还有点迷惑,下一篇你博客再写吧!嘻嘻
Entry<K,V>nexy=e.next;和e=next组合,向下遍历链表,直到为e=null
我们来看看
int i=indexFor(e.hash,newCapacity);还记得这个方法吗?是h & (length-1);
假如一开始的长度是16:
15:0000 1111
h: 1010 1010
&
=:0000 1010
新的数组的长度是32:
31:0001 1111
h: 1010 1010
&
= :0000 1010
我们发现此时和再原来table的下标是相同的。
另外一种情况:
假如h:1011 1010
和15相与:
15:0000 1111
h: 1011 1010
&
=:0000 1010
和31相与:
31:0001 1111
h: 1011 1010
&
= : 0001 1010
我们发现下标为:原table的下标+原table的长度
总结:entry e在新的table数组的下标要么和原来的table数组的下标一样,要么是原table的下标+原table的长度
这样更有利于散列,有利于把长链表拆成短链表,而且当我们tansfer之后,我们的链表也倒置了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值