ArrayList扩容源码讲解
时间: 2024-05-13 17:20:52 浏览: 71
ArrayList是Java中常用的动态数组实现类,它可以自动扩容以容纳更多的元素。下面我们来看一下ArrayList的扩容源码。
首先,ArrayList内部维护了一个数组elementData,用于存储元素。当我们向ArrayList中添加元素时,如果元素个数已经达到了数组的容量,就需要对数组进行扩容。下面是ArrayList中扩容的核心代码:
```java
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
```
在ensureCapacityInternal方法中,首先判断当前的elementData是否是默认空数组,如果是,则将minCapacity与默认容量DEFAULT_CAPACITY取最大值。这是因为默认空数组的容量为0,如果minCapacity小于DEFAULT_CAPACITY,就会直接使用默认容量。如果不是默认空数组,则直接调用ensureExplicitCapacity方法。
在ensureExplicitCapacity方法中,首先将modCount加1,表示对ArrayList进行了一次修改。然后判断需要扩容的最小容量是否大于当前数组的容量,如果是,就调用grow方法进行扩容。
在grow方法中,首先将当前数组的容量oldCapacity扩大1.5倍,得到新的容量newCapacity。然后判断新容量是否小于需要的最小容量,如果是,就将新容量设置为需要的最小容量。最后再判断新容量是否超过最大数组容量MAX_ARRAY_SIZE,如果超过,就调用hugeCapacity方法抛出异常。
最后,通过调用Arrays.copyOf方法将原数组elementData复制到新数组中,完成扩容。
总体来说,ArrayList的扩容过程就是先判断是否需要扩容,然后计算新容量,最后将原数组复制到新数组中。需要注意的是,ArrayList的扩容策略是每次扩容1.5倍,而不是每次扩容一个固定的值。这是因为这种策略可以在大多数情况下减少扩容次数,提高性能。
阅读全文