自动扩容需要满足2个条件

image.png

  • size: HashMap中key-value键值对的个数
  • threshold: 阈值 —-这个当我在首次put的时候给这个属性计算出一个值
    • 这个值的由来:threshold会根据initialCapacity(数组初始化容量)算出initialCapacity小于等于2的幂次方的值,再用这个值去loadFactor(加载因子)例如当initialCapacity为18时,算出来的值为32, 再加载因子
  • 另一个条件:null !=table[bucketIndex]

    • 表示插入值所在数组下标的位置不为空时才去扩容

      扩容实现机制

  • 在java中数组本身是无法扩容的,因为数组在创建时已经分配好了内存空间,那它怎么实现的的呢:

    • 首先会创建一个原来数组长度为2倍的一个新的数组,然后再遍历原来的数组及链表里面的

      1. 所有元素,把这里面的所有元素依次转移到新的数组当中的
    • 转移过程:把key的hash值和新的数组长度取模得到新的下标,然后进行链表的头插法进行转移

      在多线程情况下扩容有可能会出现链表循环

  • 产生的原因我个人觉得可能是头插法引起的原因之一