首页 新闻 会员 周边

HashMap底层方法putVal()方法的问题,求助大佬

0
[已解决问题] 解决于 2018-09-17 10:35

两个问题:
hashMap在添加值的时候,如果hash&(capacity-1)的位置在某个entry链的中间,也就是如下代码所示:
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
//问题一的地方
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
//问题二的地方
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
问题一,TREEIFY_THRESHOLD的默认值是8,也就是说,如果binCount的值为7的时候,链表存储就会转为红黑树存储,我想确认的是,这句话是不是说明,entry单个链最多存储6个元素,第七个元素的时候链表就会自动转换成红黑树了

问题二,问题二可以看出,如果在entry链的中间找到匹配的hash和key,就会跳出,然后还会执行下面一段代码:
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
也就是值的更新,那么我有个疑问,为什么在putVal的方法最后有一个判断语句:
if (++size > threshold)
resize();
如果是在entry链中间匹配到,那么这次的putVal算不算给这条entry链增加了长度呢,因为从上边的代码也可以看到,如果是中间匹配,他是直接更新值的。我的问题是,这条判断语句是否需要增加一个判断,判断是否中间匹配的判断。

PottyHarry的主页 PottyHarry | 菜鸟二级 | 园豆:302
提问于:2018-09-16 10:47
< >
分享
最佳答案
1

如果是存在的key 他直接return oldValue; size不会再加1了。

奖励园豆:5
让我发会呆 | 老鸟四级 |园豆:2929 | 2018-09-17 10:01

确实是这样,我粗心了。

PottyHarry | 园豆:302 (菜鸟二级) | 2018-09-17 10:34
其他回答(1)
0

哪个JDK版本

jello chen | 园豆:7336 (大侠五级) | 2018-09-16 11:27

JDK1.8的版本,然后刚刚我写了个测试,因为同样的key的hash运算是一样的,然后put两个同样的key,size值还是1,说明并没有完成size+1这个操作,只是更新了value,跟我的想法一样,那么是不是跟这边就自相矛盾,++size>threshold这个判断语句,size的值每次都会自动+1。

支持(0) 反对(0) PottyHarry | 园豆:302 (菜鸟二级) | 2018-09-16 11:34
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册