ArrayList的动态扩容机制

本文解析了ArrayList在Java中的动态扩容机制,特别关注了当初始化容量为20时的扩容行为,并详细解释了为何在这种情况下不会发生扩容。

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

先来看一道笔试题:

下面的ArrayList会扩容几次?

ArrayList<String> arrayList = new ArrayList<String>(20);

我们先看一下源码的动态扩容机制是如何实现的。下面以jdk1.7为例:

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        // 右移一位,转化为10进制即为除以2
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 第一次添加元素时,oldCapacity为0,即newCapacity为0,此时走此分支
        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);
    }

通过下面这一行

int newCapacity = oldCapacity + (oldCapacity >> 1);

我们可以看到新的容量是旧容量的1.5倍。且通过位移操作实现,比直接算术运算效率更高。

我们回过头来再看开头的笔试题,ArrayList的默认大小是10,

private static final int DEFAULT_CAPACITY = 10;

因此我们可以草率的下结论答案应该是2次。但是我们还要仔细看一下问题的根本:什么情况下才会采用动态扩容机制?

通过查看代码可以发现只有在容量不够的情况下才会采取动态扩容机制。而创建对象时指定容量为20,是不需要扩容的,

再来看一下构造方法的源码,

public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }

我们可以看到直接将传过来的初始容量传递给底层实现的数组。并没有什么扩容机制。

最后,我们再来公布开头问题的答案。经过分析,那就是扩容次数为0。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值