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);}}
推荐阅读
-
-
-
-
成为了本次世锦赛第一个杀入到8强的选手,成为了大黑马,大黑马掀翻世界第5
-
中新网|"神车"宝骏560:高速突然失去动力 故障没完投诉无门
-
『北京市地方金融监督管理局』通知|金融科技类企业在科创板上市有关意向开始征集啦
-
微软|迎接新主机:微软确认Xbox One X和One S全数字版停产
-
广州4大火车站, 各自主要承担哪些线路, 经过你家乡吗
-
中年|中国奥园发布中报:前七月销售604亿 城市更新项目加速转化
-
你觉得企业退休人员的养老金可以跟机关事业单位持平吗?
-
东方网|新时期新就业丨100个“短缺职业”,就业不妨先“以短补长”
-
热刺|穆帅利好!热刺两巨星有望提前回来,欧洲最强三叉戟或打爆曼城
-
捷克总统批评参议院主席执意访台:捷克总统批评参议院主席执意访台 外交部:赞赏
-
小院食光 馅饼这样做太好吃了,皮薄馅大,营养丰富,上桌瞬间就光盘,解馋
-
月下谈车上诉5次全败,奔驰憋屈哭:你牛,因“抄袭”车标被奔驰告上法庭
-
-
输给|情怀再次输给现实!年赚上亿的网红店鼻祖,这次真要死了
-
|日本的卫生间又火了,只有巴掌大却异常干净,看完嫌弃自家卫生间
-
-
[晨财经]两大信号暗示拐点将近,历史性刺激如何影响A股走势?