Hashmap 扩容流程?

Hashmap 扩容流程?
逐行讲解 resize 扩容方法的好文章:https://segmentfault.com/a/1190000015812438
扩容条件:
● 当 HashMap 中的元素个数超过 (数组长度) * loadFactor(负载因子) 或者 链表过长时(链表长度 > 8,数组长度 < 64),就会进行数组扩容,创建新的数组,伴随一次重新 hash 分配,并且遍历 hash 表中所有的元素非常耗时,所以要尽量避免 resize,扩容为原来容量的 2 倍。
新节点位置:

  1. HashMap 在进行扩容后,节点要么就在原来的位置,要么就被分配到"原位置 + 旧容量"的位置,具体会将所有节点分成高低位两个链表,
  2. 低位链表存放扩容后数组下标没变的节点,高位链表存放变了的节点,最后将高低位链表插入新数组中。
    具体流程:
  3. 重新建立一个新的数组,长度为原数组的两倍;
  4. 遍历旧数组的每个数据,重新计算每个元素在新数组中的存储位置。使用节点的 hash 值与旧数组长度进行位与运算,如果运算结果为 0,表示元素在新数组中的位置不变;否则,则在新数组中的位置下标=原位置 + 原数组长度。
  5. 将旧数组上的每个数据使用尾插法逐个转移到新数组中,并重新设置扩容阈值。

会遍历每个哈希桶,如果只有一个节点的话,就直接插入到 e.hash & (newCap - 1) 的位置;如果是链表,将原来的链表拆分成两个链表, lo 链表和 hi 链表,并将这两个链表分别放到新的table的 j 位置和 j + oldCap 上, j 位置就是原链表在原 table 中的位置, 拆分的标准就是:如果 (e.hash & oldCap) == 0,就放到原本的位置上

你可能感兴趣的:(集合,1024程序员节,HashMap)