关于源码:HashMap的转化时机

45次阅读

共计 770 个字符,预计需要花费 2 分钟才能阅读完成。

HashMap 的转化机会

    /**
    * 应用红黑树 (而不是链表) 来寄存元素。当向至多具备这么多节点的链表再增加元素时,链表就将转换为红黑树。* 该值必须大于 2,并且应该至多为 8,以便于删除红黑树时转回链表。*/
    static final int TREEIFY_THRESHOLD = 8;
    /**
     *  当桶数组容量小于该值时,优先进行扩容,而不是树化:*/
    static final int MIN_TREEIFY_CAPACITY = 64;

putval 片段

…………

else { // 上面的代码是探索“链表转红黑树”的重点:for (int binCount = 0;; ++binCount) {if ((e = p.next) == null) { 
            // 沿着 p 节点,找到该桶上的最初一个节点:p.next = newNode(hash, key, value, null); // 间接生成新节点,链在最初一个节点的前面;//“binCount >= 7”:p 从链表.index(0)开始,// 当 binCount == 7 时,p.index == 7,newNode.index == 8;// 也就是说,当链表曾经有 8 个节点了
            // 此时再新链上第 9 个节点,在胜利增加了这个新节点之后,立马做链表转红黑树。if (binCount >= TREEIFY_THRESHOLD - 1)
              treeifyBin(tab, hash); 
            // 链表转红黑树 break;             
        }            
………… 

如果你的 table 总容量小于 64 就不给你树化了,哪怕你一个单链的元素个数超过了 8 个,不树化,而是进行扩容。

  1. 插入第一个元素时,初始扩容;
  2. 当插入元素个数达到 threshold 扩容阈值时,扩容
  3. 当某个地位元素≥8 个时,即单链长度≥8,且 map 容量小于 64,扩容。

所以,正确应该是 数组长度大于 64,并且链表长度大于 8,转化树。

正文完
 0