前言
在Java中,ArrayList 是一个动态数组实现,它可以根据需要自动扩容。ArrayList 扩容的机制是在容量不足时,自动增加容量并将元素复制到新的数组中。
add() 方法
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
add()方法源码
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
ensureCapacityInternal(size + 1)这是一个私有方法,用于确保ArrayList内部数组的容量足够来容纳至少指定数量的元素。size + 1表示添加一个元素后的预期大小。如果内部数组的容量不够,该方法会触发扩容操作
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 触发扩容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
ensureCapacityInternal(int minCapacity) 方法:这个方法用于确保 ArrayList 内部数组的容量足够大,以容纳至少 minCapacity 个元素。它会调用 ensureExplicitCapacity() 方法来实现这一目标。
calculateCapacity(Object[] elementData, int minCapacity) 方法作用
首先,它检查 elementData 是否等于 DEFAULTCAPACITY_EMPTY_ELEMENTDATA【表示新建数组,还没添加元素】
- 如果创建数组没有指定数组大小
ArrayList<Integer> list = new ArrayList<>();
则会返回默认值(默认容量DEFAULT_CAPACITY
大小为10) - 否则返回自己创建时指定的大小,例如:
ArrayList<Integer> list = new ArrayList<>(20);
则返回20
ensureExplicitCapacity(int minCapacity) 方法:这个方法是实际执行扩容操作的地方。它首先增加了 modCount,这是一个用于记录修改次数的计数器。然后,它检查当前容量是否足够,如果不足,就会调用 grow(minCapacity) 方法进行扩容。
grow(int minCapacity) 方法:这个方法负责实际的扩容操作。它会创建一个新的数组,并将原有数组中的元素复制到新的数组中。新数组的大小通常是原数组大小的1.5倍(也就是原数组大小加上原数组大小的一半) 。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
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倍。 (oldCapacity >> 1)
二进制中右移一位,表示除以2
小结
ArrayList的默认容量是10 。默认情况下,ArrayList的扩容策略是每次扩容增加当前容量的一半,即增加50%。当需要扩容时,ArrayList会创建一个新的容量更大的数组,并将原始数组中的元素复制到新数组中。
感谢观看,欢迎指点。