ArrayList扩容原理


ArrayList的扩容原理

摘要:本文旨在透彻解析 Java 中ArrayList的动态扩容机制。 从原理到实践,我们将揭示这一流行数据结构背后的调整策略,为开发者提供优化代码和提升性能的见解。


引言

在数据集合持续增长的现代编程中,如何优雅地管理内存是衡量一个优秀程序的关键。ArrayList,作为Java集合框架的一员,优秀地解决了数组静态大小的限制。本文将详解ArrayList动态扩容的内部工作机制。

1. 底层代码

private void ensureCapacityInternal(int minCapacity) {
    // 如果ArrayList为空,则选择默认容量和传入容量的较大值作为新容量
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    // 确保ArrayList的容量足够存储minCapacity个元素
    ensureExplicitCapacity(minCapacity);
}

private void ensureExplicitCapacity(int minCapacity) {
    // 修改操作次数加1
    modCount++;

    // 如果minCapacity大于当前容量,则进行扩容操作
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

private void grow(int minCapacity) {
    // 原容量
    int oldCapacity = elementData.length;

    // 新容量是原容量的1.5倍,并向上取整
    int newCapacity = oldCapacity + (oldCapacity >> 1);

    // 如果新容量小于minCapacity,则直接使用minCapacity作为新容量
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;

    // 如果新容量大于最大容量,则使用最大容量作为新容量
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);

    // 将原始数组拷贝到新数组中,实现扩容
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    // 如果minCapacity大于最大容量,则抛出OutOfMemoryError异常
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}

2. ArrayList扩容方式原理

  1. 当需要添加元素时,ArrayList会先判断当前容量是否足够,如果不足够,则需要进行扩容操作。
  2. 扩容操作的第一步是调用ensureCapacityInternal方法,该方法用于确定扩容后的最小容量。
  3. 如果ArrayList为空,则选择默认容量和传入容量的较大值作为新容量。
  4. 然后调用ensureExplicitCapacity方法,该方法用于判断是否需要进行扩容操作。
  5. ensureExplicitCapacity方法中,修改操作次数加1,然后判断如果需要的最小容量大于当前容量,则进行扩容操作。
  6. 扩容操作的第二步是调用grow方法,该方法用于计算新的容量并进行扩容。
  7. 首先获取当前的容量,然后计算新的容量,一般是原容量的1.5倍,并向上取整。
  8. 如果新容量小于所需的最小容量,则直接使用最小容量作为新容量。
  9. 如果新容量超过了最大容量限制,则使用最大容量作为新容量。
  10. 最后,通过调用Arrays.copyOf方法,将原始数组拷贝到新数组中,实现扩容。

3. 结论

总的来说,ArrayList的扩容方式是通过动态调整容量大小的方式来实现的。当需要添加元素时,如果当前容量不足够,就会进行扩容操作。扩容操作会计算新的容量大小,并将原始数组拷贝到新的数组中,从而实现容量的增加。扩容操作可以提高ArrayList的添加元素的效率,但是在进行扩容时会带来一定的性能开销。因此,在使用ArrayList时,如果事先能够估计到元素的数量,可以通过调用ensureCapacity方法来指定初始容量,从而减少扩容次数,提高效率。

4. 参考文献

  • Effective Java, Joshua Bloch
  • Java Collection Framework documentation
  • ArrayList source code analysis

关于作者:猿究院——屠龙少年SlayMaster

版权声明:创作不易,版权需敬, 笑一笑,传播正能量!

评论区:灵感闪现,友谊加码, 一句顶俏,乐开花!

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值