共同学习Java源代码-数据结构-HashMap(六)
来源:互联网 发布:win10手写识别软件 编辑:程序博客网 时间:2024/06/11 04:57
return putVal(hash(key), key, value, false, true);
}
这个方法也是非常常用的put方法 调用的是下面的putVal方法 将键的哈希值 键 以及两个布尔参数传到下面的方法里 第一个布尔值为false表示添加的键值如果存在就覆盖 第二个为true代表不是creation模式 第二个参数什么意思真不清楚 听说HashMap里用不上这个参数
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
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;
}
}
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
首先创建临时变量 节点数组类型的tab 节点类型的p int类型的n i
将哈希桶数组赋给tab 判断tab为空或tab的长度为空 也就是哈希桶数组没有元素
调用resize方法创建一个新的哈希桶数组赋给tab 将新哈希桶数组的长度赋给n
再将(n - 1) & hash值赋给i 找到i对应的哈希桶数组元素 也就是该键的哈希值对应的桶的第一个元素 如果这个第一个元素为空 就创建一个新节点 将键值对放入这个新节点
如果该桶元素对应的链表的首节点不为空 那就继续以下的操作
创建临时变量节点类型的e和键类型k
判断如果桶元素 也就是链表的起点元素的键和传入的键相等或为同一对象 那么就将这个链表的首元素赋给e
判断如果链表已经升级成了树 也就是链表元素超过了8 调用树对象的putTreeVal方法将键值对添加进去
如果哈希桶收元素的键和要添加的键不一样 且链表尚未升级成树 就进入一个无休止的for循环 循环变量为binCount 进入循环后 先遍历链表找到一个空节点 新建节点 然后判断binCount循环了多少次 一旦超过链表变成树的阈值 则调用treeify方法将链表升级成树 并终止循环
然后判断遍历中的节点的键是否和要添加的键相等或为同一对象 如果是 就将e赋值为该节点 然后中止循环
循环结束后 判断e是否为空 如果e不为空说明链表中已经有了该键的节点 判断如果onliIfAbsent为false 也就是覆盖添加 或者该节点值为空 就将新的值替换为旧的值 然后将旧的值返回
afterNodeAccess(e);为空方法 HashMap未予以实现
然后将modCount自增 代表修改次数加一
再判断如果size也就是整个键值对总数自增后超过了哈希桶扩容的阈值 则调用resize方法将哈希桶扩容
afterNodeInsertion(evict);为空方法实现
最后返回空 也就是之前不存在这个键值对的情况下进行添加
- 共同学习Java源代码-数据结构-HashMap(六)
- 共同学习Java源代码-数据结构-HashMap(一)
- 共同学习Java源代码-数据结构-HashMap(二)
- 共同学习Java源代码-数据结构-HashMap(三)
- 共同学习Java源代码-数据结构-HashMap(四)
- 共同学习Java源代码-数据结构-HashMap(五)
- 共同学习Java源代码-数据结构-HashMap(七)
- 共同学习Java源代码-数据结构-HashMap(八)
- 共同学习Java源代码-数据结构-HashMap(九)
- 共同学习Java源代码-数据结构-HashMap(十)
- 共同学习Java源代码-数据结构-HashMap(十一)
- 共同学习Java源代码-数据结构-HashMap(十二)
- 共同学习Java源代码-数据结构-HashMap(十三)
- 共同学习Java源代码-数据结构-HashMap(十四)
- 共同学习Java源代码-数据结构-HashMap(十五)
- 共同学习Java源代码-数据结构-HashMap(十六)
- 共同学习Java源代码-数据结构-HashMap(十七)
- 共同学习Java源代码-数据结构-HashMap(十八)
- iOS开发——Swift字符串替换 + HTML标签正则过滤 + 主线程非阻断延时
- 1047. 编程团体赛(20)——C语言
- Java maven打包 多个main方法
- 刷新头布局 帧动画的实现
- 在kali下使用gdb以源码方式调试glibc
- 共同学习Java源代码-数据结构-HashMap(六)
- 1秒识别汽车Vin码,告别手动录入
- 机器学习应用之WebShell检测
- 最新管家婆工贸版ERP T3 V16.5生产加工一体化网络版破解
- 微信参数 sha1 加密
- vue2.0从入门到努力(1)--安装环境
- 说说DNS在wireshark里的抓包内容(二)
- Mysql 算出周一跟周日的日期
- 326. Power of Three