欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ArrayList扩容机制(基于底层代码讲解)

程序员文章站 2023-11-05 12:14:34
ArrayList扩容机制ArrayList的扩容发生在add()方法调用的时候add()源码:public boolean add(E e) { //扩容 ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }根据add源码可看出ensureCapacityInternal() 是用来...

ArrayList扩容机制

ArrayList的扩容发生在add()方法调用的时候

add()源码:

public boolean add(E e) {
       //扩容
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

根据add源码可看出ensureCapacityInternal() 是用来扩容的,形参为最小扩容量,进入ensureCapacityInternal()之后:

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

通过方法calculateCapacity(elementData, minCapacity) 获取:

private static int calculateCapacity(Object[] elementData, int minCapacity) {
        //如果传入的是个空数组则最小容量取默认容量与minCapacity之间的最大值
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

ensureExplicitCapacity() 方法可以判断是否需要扩容:

private void ensureExplicitCapacity(int minCapacity) {
          modCount++;
          // 如果最小需要空间比elementData的内存空间要大,则需要扩容
          if (minCapacity - elementData.length > 0)
              //扩容              
              grow(minCapacity);
      }

扩容的关键方法为grow():

private void grow(int minCapacity) {
          // 获取到ArrayList中elementData数组的内存空间长度
          int oldCapacity = elementData.length;
         // 扩容至原来的1.5倍
         int newCapacity = oldCapacity + (oldCapacity >> 1);
         // 再判断一下新数组的容量够不够,够了就直接使用这个长度创建新数组,
          // 不够就将数组长度设置为需要的长度
         if (newCapacity - minCapacity < 0)
             newCapacity = minCapacity;
         //若预设值大于默认的最大值检查是否溢出
         if (newCapacity - MAX_ARRAY_SIZE > 0)
             newCapacity = hugeCapacity(minCapacity);
         // 调用Arrays.copyOf方法将elementData数组指向新的内存空间时newCapacity的连续空间
         // 并将elementData的数据复制到新的内存空间
         elementData = Arrays.copyOf(elementData, newCapacity);
     }

通过grow()方法可以清晰的看出ArrayList扩容的本质是计算出新的扩容数组的size后实例化,并将原有数据的内容复制到新的数组中去。

原文链接:https://www.cnblogs.com/dengrongzhang/p/9371551.html

本文地址:https://blog.csdn.net/weixin_43931723/article/details/107066279