Bootstrap

ArrayList扩容机制解析

问题:

刷面经,博客输出,加深印象,2025.3.4 希望毕业前找到工作。

扩容流程:

在这里插入图片描述
在这里插入图片描述

源码解析:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
   
    /**
     * Default initial capacity.
     * 默认初始化容量
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 
     * Shared empty array instance used for empty instances.
     * 创建空数组实例,默认容量为空
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     * 创建空数组实例,数组默认容量是10,但实际数组是空的,只有第一次添加元素后,才会真正
     * 是默认容量
     */

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     * 
     * 说白了就是真正存储数据的数组
     * 空的数组  elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     *当添加第一个元素时, elementData == DEFAULT_CAPACITY
     */
    transient Object[] elementData; // non-private to simplify nested class access

    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialCapacity  the initial capacity of the list
     * @throws IllegalArgumentException if the specified initial capacity
     *         is negative
     */
    public ArrayList(int initialCapacity) {
        //指定容量初始化
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            //初始化为数组为空
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        //初始实际数组为空,但是默认容量是10的数组
        //当添加第一个元素时,才会真正是容量是10
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

   
    /**
     * Increases the capacity of this {@code ArrayList} instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     */
    public void ensureCapacity(int minCapacity) {
        if (minCapacity > elementData.length
            && !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
                 && minCapacity <= DEFAULT_CAPACITY)) {
            modCount++;
            grow(minCapacity);
        }
    }

    /**
     * Increases the capacity to ensure that it can hold at least the
     * number of elements specified by the minimum capacity argument.
     *
     * @param minCapacity the desired minimum capacity
     * @throws OutOfMemoryError if minCapacity is less than zero
     */
    private Object[] grow(int minCapacity) {



        int oldCapacity = elementData.length;

        //oldCapacity大于0,一定是已经初始化过了,
        //所以,这里判断的是是否已经初始化过或者是不是第一次添加元素
        if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {

            //计算出一个新的长度
            int newCapacity = ArraysSupport.newLength(oldCapacity,

                    //比如是10个已经满了,再添加1个  11 - 10=1,也就是最小必须得增加1个
                    minCapacity - oldCapacity, /* minimum growth */

                    // oldCapacity / 2   比如默认是10  ,那推介在增加10/2个  也就说扩容1.5倍
                    oldCapacity >> 1           /* preferred growth */);

            //复制新数组
            return elementData = Arrays.copyOf(elementData, newCapacity);
        } else {
            //
            return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
        }
    }

    private Object[] grow() {
        //当前size =10,需要扩容,最小扩容为size + 1 = 10 +1
        return grow(size + 1);
    }

   
    

}


/*
oldLength: 旧容量
minGrowth: 最小增长长度,比如你需要再添加1个,那就是10+1=11
prefGrowth:推介增长量,让满足可以添加的情况下,再增加一些
*/

public static int newLength(int oldLength, int minGrowth, int prefGrowth) {
    // preconditions not checked because of inlining
    // assert oldLength >= 0
    // assert minGrowth > 0

    //计算长度
    int prefLength = oldLength + Math.max(minGrowth, prefGrowth); // might overflow
    //防止数组超出最大最小限制
    if (0 < prefLength && prefLength <= SOFT_MAX_ARRAY_LENGTH) {
        //没有超出范围,我都是优先推介的范围
        return prefLength;
    } else {
        //如果 推介范围超出了,则用最小范围
        return hugeLength(oldLength, minGrowth);
    }
}

//保证最小的长度,eg.10个已经满了,我需要再添加1个,也就是增加1个容量,即11
 private static int hugeLength(int oldLength, int minGrowth) {
        
        //旧长度+最小增长率=最小的扩容容量,刚刚满足好最小范围    
        int minLength = oldLength + minGrowth;

        //防止超出范围
        if (minLength < 0) { // overflow
            throw new OutOfMemoryError(
                "Required array length " + oldLength + " + " + minGrowth + " is too large");
        } else if (minLength <= SOFT_MAX_ARRAY_LENGTH) {
            return SOFT_MAX_ARRAY_LENGTH;
        } else {
            return minLength;
        }
    }
;