关于 treeifyBin
替换给定哈希值的bin中的所有链接节点,除非表太小,在这种情况下,会调用 resize 调整大小。
treeifyBin方法,应该可以解释为:把容器里的元素变成树结构。当HashMap的内部元素数组中某个位置上存在多个hash值相同的键值对,这些Node已经形成了一个链表,当该链表的长度大于等于9(为什么是9?TREEIFY_THRESHOLD默认值为8呀?
源码
1、treeifyBin
/*** Replaces all linked nodes in bin at index for given hash unless* table is too small, in which case resizes instead.*/final void treeifyBin(Node<K,V>[] tab, int hash) {int n, index; Node<K,V> e;if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)resize();else if ((e = tab[index = (n - 1) & hash]) != null) {TreeNode<K,V> hd = null, tl = null;do {TreeNode<K,V> p = replacementTreeNode(e, null);if (tl == null)hd = p;else {p.prev = tl;tl.next = p;}tl = p;} while ((e = e.next) != null);if ((tab[index] = hd) != null)hd.treeify(tab);}}
2、treeifyBin 源码注释
/*** Replaces all linked nodes in bin at index for given hash unless* table is too small, in which case resizes instead.*//*** tab:元素数组* hash:hash值(要增加的键值对的key的hash值)*/final void treeifyBin(Node<K,V>[] tab, int hash) {// 定义辅助变量int n, index; Node<K,V> e;/** 如果元素数组为空 或者 数组长度小于 树结构化的最小限制* MIN_TREEIFY_CAPACITY 默认值64*/if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)// 如果元素数组长度小于这个值,Java 的开发人员认为此时 tab 太小// 没有必要过早去进行结构转换,调用 resize 扩容即可。// 当一个数组位置上集中了多个键值对,那是因为这些 key 的 hash 值和数组长度取模之后结果相同//(并不是因为这些key的hash值相同)// 因为 hash 值相同的概率不高,所以可以通过扩容的方式,来使得最终这些 key 的 hash 值在和 新的数组长度-1 取模之后,拆分到多个数组位置上。resize();// 如果元素数组长度已经大于等于了 MIN_TREEIFY_CAPACITY,那么就有必要进行结构转换了// 根据hash值和数组长度进行取模运算后,计算红黑树根节点位置索引,判断该索引位置是否已经存放了元素。else if ((e = tab[index = (n - 1) & hash]) != null) {// 该索引位置为空,new 一个红黑树的根节点出来TreeNode<K,V> hd = null, tl = null;do {// 将链表转换为红黑树TreeNode<K,V> p = replacementTreeNode(e, null);// 如果尾节点为空,说明还没有根节点if (tl == null)// 首节点(根节点)指向 当前节点hd = p;// 尾节点不为空,以下两行是一个双向链表结构else {// 当前树节点的 前一个节点指向 尾节点p.prev = tl;// 尾节点的 后一个节点指向 当前节点tl.next = p;}// 把当前节点设为尾节点tl = p;// 遍历链表,重复以上步骤} while ((e = e.next) != null);// 到目前为止 也只是把 Node 对象转换成了 TreeNode 对象,把单向链表转换成了双向链表// 把转换后的双向链表,替换原来位置上的单向链表if ((tab[index] = hd) != null)hd.treeify(tab);}}
https://blog.csdn.net/weixin_42340670/article/details/80503863
