源码分析

  • 以add方法来分析,其他同理 ```java // ArrayList内部存储的数组变量 transient Object[] elementData; // 统计当前数组列表中已写入的元素 private int size

/**

  • 以ArrayList的add方法源码分析 */ public boolean add(E e) { // 校验是否需要扩容(以当前数组列表中元素个数size加1来判断) ensureCapacityInternal(size + 1); // Increments modCount!! // 容量足够或已扩容的情况下,将元素插入到数组列表(elementData)中 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } // 计算数组列扩容后值capacity private static int calculateCapacity(Object[] elementData, int minCapacity) { // 若数组列表为空,则返回 10 和 size+1 中最小的值 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

    1. return Math.max(DEFAULT_CAPACITY, minCapacity);

    } // 否则返回 size+1 值 return minCapacity; } // 确定是否需要扩容 private void ensureExplicitCapacity(int minCapacity) { modCount++;

    // 判断计算后的扩容值capacity是否大于数组列表本身的容量,是则扩容,否则不变 if (minCapacity - elementData.length > 0)

    1. grow(minCapacity);

    } // 扩容数组列表 private void grow(int minCapacity) { // 获取默认扩容值 [公式:原来的容量 + (原来的容量 / 2)取整] int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); // 获取最终扩容值newCapacity:默认扩容值 与 传入的容量minCapacity 中的最大的扩容值 if (newCapacity - minCapacity < 0)

    1. newCapacity = minCapacity;

    if (newCapacity - MAX_ARRAY_SIZE > 0)

    1. newCapacity = hugeCapacity(minCapacity);

    // 扩容(根据新的扩容值newCapacity,构造新的数组,并将旧的数组按序拷贝到新数组中,并取代旧的数组elementData) elementData = Arrays.copyOf(elementData, newCapacity); } ```

逻辑流程

  • 校验是否需要扩容(以当前数组列表中元素个数size加1来判断)
    • 计算数组列扩容后值capacity
      • 校验数组列表是否为空,是则返回 10 和 size+1 中最小的值
      • 否则返回 size+1 值
      • Tips:size为数组列表中实际的元素数量
    • 确定是否需要扩容,若需要则进行扩容,否则返回
      • 判断计算后的扩容值capacity是否大于数组列表本身的容量
      • 不是,则直接返回
      • 否则,则执行扩容操作
    • 执行扩容操作
      • 获取默认扩容值
        • 公式:原来的容量 + (原来的容量 / 2)取整
      • 获取最终扩容值newCapacity
        • 默认扩容值 与 计算后扩容值capacity 中的最大值
      • 进行扩容
        • 根据新的扩容值newCapacity
        • 构造新的数组
        • 并将旧的数组按序拷贝到新数组中
        • 并取代旧的数组(elementData)
  • 容量足够或已扩容的情况下,将元素插入到数组列表(elementData)中
  • 返回成功