飞利浦·斯塔克|厉害了!阿里大佬把 HashMap 剖析得只剩渣渣了( 五 )


       newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
   
   // 如果原数组长度小于16或者翻倍之后超过了最大限制长度 , 则重新计算阈值
   if (newThr == 0) {
       float ft = (float)newCap * loadFactor;
       newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
                 (int)ft : Integer.MAX_VALUE);
   
   threshold = newThr;

   @SuppressWarnings({\"rawtypes\"\"unchecked\")
   // 建立新的数组
   Node<KV>[
newTab = (Node<KV>[
)new Node[newCap
;
   table = newTab;
   if (oldTab != null) {
       // 循环遍历原数组 , 并给每个节点计算新的位置
       for (int j = 0; j < oldCap; ++j) {
           Node<KV> e;
           if ((e = oldTab[j
) != null) {
               oldTab[j
= null;
               // 如果他没有后继节点 , 那么直接使用新的数组长度取模得到新下标
               if (e.next == null)
                   newTab[e.hash & (newCap - 1)
= e;
               // 如果是红黑树 , 调用红黑树的拆解方法
               else if (e instanceof TreeNode)
                   ((TreeNode<KV>)e).split(this newTab j oldCap);
               // 新的位置只有两种可能:原位置 , 原位置+老数组长度
               // 把原链表拆成两个链表 , 然后再分别插入到新数组的两个位置上
               // 不用多次调用put方法
               else {
                   // 分别是原位置不变的链表和原位置+原数组长度位置的链表
                   Node<KV> loHead = null loTail = null;
                   Node<KV> hiHead = null hiTail = null;
                   Node<KV> next;
                   // 遍历老链表 , 判断新增判定位是1or0进行分类
                   do {
                       next = e.next;
                       if ((e.hash & oldCap) == 0) {
                           if (loTail == null)
                               loHead = e;
                           else
                               loTail.next = e;
                           loTail = e;
                       
                       else {
                           if (hiTail == null)
                               hiHead = e;
                           else
                               hiTail.next = e;
                           hiTail = e;
                       
                    while ((e = next) != null);
                   // 最后赋值给新的数组
                   if (loTail != null) {
                       loTail.next = null;