ArrayList扩容方式的理解

文章详细介绍了ArrayList在Java中的初始化过程,包括无参构造和有参构造时的不同处理。在添加元素时,通过add()方法触发扩容,确保Capacity足够。扩容主要由grow()方法执行,通常按原容量的1.5倍增长。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、初始化

构造方法不同扩容的方式不同。

1.无参构造

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

 elementData指向DEFAULTCAPACITY_EMPTY_ELEMENTDATA常量。

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//空数组

即将内部数组初始化为一个长度为0的空数组。

第一次添加元素时扩容为10,之后每次扩容为原来的1.5倍。

2.有参构造

    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) { // 初始化容量 > 0
            this.elementData = new Object[initialCapacity]; // 数组长度为初始化容量
        } else if (initialCapacity == 0) { // 初始化容量 = 0
            this.elementData = EMPTY_ELEMENTDATA; // 数组长度为空数组
        } else { // 初始化容量 < 0
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity); //抛异常
        }
    }

有参构造方法,按照指定容量进行数组初始化,容量不足时产生扩容,为原来的1.5倍。

二、add()

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // 确保数组容量够用
    elementData[size++] = e; // 将元素放入element数组
    return true;
}

当数组需要添加元素时,调用add()方法,add()方法再通过ensureCapacityInternal(int minCapacity)方法确保数组容量够用。

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

ensureCapacityInternal(int minCapacity)方法将minCapacity(最小所需容量,即(size + 1))传入calculateCapacity(Object[] elementData, int minCapacity)方法中。

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}

calculateCapacity(Object[] elementData, int minCapacity)方法中会判断数组是否为空数组,如是,则将minCapacity与DEFAULT_CAPACITY(常量10)比较,取最大值,即无参构造第一次添加元素时扩容为10,否则返回minCapacity。

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

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

再将minCapacity传入ensureExplicitCapacity(int minCapacity)中与数组长度比较,如所需最小容量大于数组长度时调用grow()方法。

三、grow()

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length; // 原来数组长度
    int newCapacity = oldCapacity + (oldCapacity >> 1); 
    // 新容量 = 原来长度+(原来长度/2)=1.5原长度
    if (newCapacity - minCapacity < 0) // 新容量 < 最小所需容量
        newCapacity = minCapacity; // 将最小所需容量赋予新容量
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity); // 将原数组中的元素复制到新数组
}

即容量不足时,按照原容量的1.5倍扩容增长创建新数组,copy原数组至新数组。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值