ArrayList扩容

98 阅读1分钟

默认容量为10

ArrayList<Integer> integers = new ArrayList<>();

但此时内部数组是空对象

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

当首次执行add方法时才会进行扩容,生成一个大小为10的数组,并将新加的元素赋值数组第一个单元

每次执行add方法时,会先检查内部数组大小是否能容纳新增元素

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

如果需要的最小容量小于实际数组大小,则调用grow方法进行扩容

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

扩容为原来的1.5倍,首次扩容时,即初始数组还是空对象时,新容量为默认容量10,实际扩容会执行Arrays.copyOf()方法

public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
    @SuppressWarnings("unchecked")
    T[] copy = ((Object)newType == (Object)Object[].class)
        ? (T[]) new Object[newLength]
        : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    System.arraycopy(original, 0, copy, 0,
                     Math.min(original.length, newLength));
    return copy;
}

先生成指定大小的数组空间,再执行系统方法System.arraycopy完成复制,这是一个native方法,最后返回新数组,旧数组由gc回收