Java集合:ArrayList扩容机制

ArrayList继承了AbstractList类,实现了List接口
其扩容开始于添加元素的add方法,其添加元素有两种方法:

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

public void add(int index, E element) {
     rangeCheckForAdd(index);

     ensureCapacityInternal(size + 1);  // Increments modCount!!
     System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
     elementData[index] = element;
     size++;
}

(重点1:扩容机制的核心) 可以发现两个方法都用了ensureCapacityInternal(),把数组长度加1,以确保能存下一个数据。
首先,得到最小容量 如下源码所示,如果数组elementData为默认空数组(初始未设置容量),最小容量minCapacity置为:其(1)与DEFAULT_CAPACITY(10)的最大值,即10。否则保持minCapcity本身修改后的值。

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

(重点2:进行是否扩容判断) 得到最小容量后,执行ensureExplicityCapacity(minCapacity),判断最小容量与当前数组长度的大小,大于当前数组长度,则执行grow方法()扩容,否则不扩容。

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

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

(重点3:grow方法:真正实现扩容的方法)
新容量 = 旧容量的1.5倍
如果 新容量 < 最小容量,则不需要扩容计算,新容量 = 最小容量;
如果 新容量 > MAX_ARRAY_SIZE(即达到列表最大临界值),进入hugeCapacity(minCapacity) 再次进行判断:
如果最小容量 > MAX_ARRAY_SIZE(最小容量达到列表最大临界值),返回Integer最大值;
否则,返回MAX_ARRAY_SIZE(临界最大值)。

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);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

参考链接:
https://blog.csdn.net/u010890358/article/details/80515284?utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-2.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~default-2.no_search_link
https://blog.csdn.net/qq_26542493/article/details/88873168

posted @ 2021-10-04 11:14  aguo718  阅读(347)  评论(0编辑  收藏  举报