next){return new Node<>(hash, key, value, next);}注意第四个参数next是null , 因为当前元素插入到链表末尾了 , 那么下一个节点肯定是null2)这种添加方式也满足链表数据结构的特点 , 每次向后添加新的元素*/p.next = newNode(hash, key, value, null);/*1)节点添加完成之后判断此时节点个数是否大于TREEIFY_THRESHOLD临界值8 , 如果大于则将链表转换为红黑树2)int binCount = 0 :表示for循环的初始化值 。 从0开始计数 。 记录着遍历节点的个数 。 值是0表示第一个节点 , 1表示第二个节点 。。。。 7表示第八个节点 , 加上数组中的的一个元素 , 元素个数是9TREEIFY_THRESHOLD - 1 --》8 - 1 ---》7如果binCount的值是7(加上数组中的的一个元素 , 元素个数是9)TREEIFY_THRESHOLD - 1也是7 , 此时转换红黑树*/if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st//转换为红黑树treeifyBin(tab, hash);// 跳出循环break;}/*执行到这里说明e = p.next 不是null , 不是最后一个元素 。 继续判断链表中结点的key值与插入的元素的key值是否相等*/if (e.hash == hash/*说明新添加的元素和当前节点不相等 , 继续查找下一个节点 。用于遍历桶中的链表 , 与前面的e = p.next组合 , 可以遍历链表*/p = e;}}/*表示在桶中找到key值、hash值与插入元素相等的结点也就是说通过上面的操作找到了重复的键 , 所以这里就是把该键的值变为新的值 , 并返回旧值这里完成了put方法的修改功能*/if (e != null) {// 记录e的valueV oldValue = http://kandian.youth.cn/index/e.value;// onlyIfAbsent为false或者旧值为nullif (!onlyIfAbsent || oldValue == null)//用新值替换旧值//e.value 表示旧值value表示新值e.value = value;// 访问后回调afterNodeAccess(e);// 返回旧值return oldValue;}}//修改记录次数++modCount;// 判断实际大小是否大于threshold阈值 , 如果超过则扩容if (++size> threshold)resize();// 插入后回调afterNodeInsertion(evict);return null;} 4.3.2将链表转换为红黑树的treeifyBin方法节点添加完成之后判断此时节点个数是否大于TREEIFY_THRESHOLD临界值8 , 如果大于则将链表转换为红黑树 , 转换红黑树的方法 treeifyBin , 整体代码如下:
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st//转换为红黑树 tab表示数组名hash表示哈希值treeifyBin(tab, hash);treeifyBin方法如下所示:
/*** Replaces all linked nodes in bin at index for given hash unless* table is too small, in which case resizes instead.替换指定哈希表的索引处桶中的所有链接节点 , 除非表太小 , 否则将修改大小 。Node[] tab = tab 数组名int hash = hash表示哈希值*/final void treeifyBin(Node[] tab, int hash) {int n, index; Node e;/*如果当前数组为空或者数组的长度小于进行树形化的阈值(MIN_TREEIFY_CAPACITY = 64),就去扩容 。 而不是将节点变为红黑树 。目的:如果数组很小 , 那么转换红黑树 , 然后遍历效率要低一些 。 这时进行扩容 , 那么重新计算哈希值, 链表长度有可能就变短了 , 数据会放到数组中 , 这样相对来说效率高一些 。*/if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)//扩容方法resize();else if ((e = tab[index = (n - 1)do {//新创建一个树的节点 , 内容和当前链表节点e一致TreeNode p = replacementTreeNode(e, null);if (tl == null)//将新创键的p节点赋值给红黑树的头结点hd = p;else {/*p.prev = tl:将上一个节点p赋值给现在的p的前一个节点tl.next = p;将现在节点p作为树的尾结点的下一个节点*/p.prev = tl;tl.next = p;}tl = p;/*e = e.next 将当前节点的下一个节点赋值给e,如果下一个节点不等于null则回到上面继续取出链表中节点转换为红黑树*/} while ((e = e.next) != null);/*让桶中的第一个元素即数组中的元素指向新建的红黑树的节点 , 以后这个桶里的元素就是红黑树而不是链表数据结构了*/if ((tab[index] = hd) != null)hd.treeify(tab);}}
推荐阅读
-
刘涛|杨超越现身刘涛直播间秀美腿,刘涛状态太好,相差20岁却似姐妹
-
大学生|中国烟草招聘,3个“硬性条件”缺一不可,符合的大学生才能报
-
搞笑特浪普君|你这运动方式,伤了多少男士的腰!,搞笑gif趣图:姑娘
-
-
退伍军人福利到了,持证就能领3项补贴,战友互相转告
-
-
「琴挑文君」女婿天天让他喝剩汤, 邻居多嘴一句话, 老汉愣了,老汉进城看孙子,
-
-
冬天吃雪糕的幽默说说-冬天吃雪糕的句子-冬天吃雪糕的心情句子
-
『应届生』中央发布毕业生就业新大招,应届生拍手称快,往届生晴天霹雳!
-
刘强东|马化腾:我最终还是对我的大哥下手了,谁让你从前对我爱答不理
-
-
英媒:电商污染环境有多严重 亚马逊每年塑料包装物可绕地球500圈
-
热点时报|是喜欢是无奈?,很多退休人员在外做食堂杂工、门岗、保洁等工作
-
-
-
-
-
星了个星座|更有富贵命,一生总能财源滚滚的四大生肖,特有富贵相
-
淘宝直通车调价技巧 淘宝直通车的基准出价是什么意思