源码分析
- 以add方法来分析,其他同理 ```java // ArrayList内部存储的数组变量 transient Object[] elementData; // 统计当前数组列表中已写入的元素 private int size
/**
以ArrayList的add方法源码分析 */ public boolean add(E e) { // 校验是否需要扩容(以当前数组列表中元素个数size加1来判断) ensureCapacityInternal(size + 1); // Increments modCount!! // 容量足够或已扩容的情况下,将元素插入到数组列表(elementData)中 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } // 计算数组列扩容后值capacity private static int calculateCapacity(Object[] elementData, int minCapacity) { // 若数组列表为空,则返回 10 和 size+1 中最小的值 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
} // 否则返回 size+1 值 return minCapacity; } // 确定是否需要扩容 private void ensureExplicitCapacity(int minCapacity) { modCount++;
// 判断计算后的扩容值capacity是否大于数组列表本身的容量,是则扩容,否则不变 if (minCapacity - elementData.length > 0)
grow(minCapacity);
} // 扩容数组列表 private void grow(int minCapacity) { // 获取默认扩容值 [公式:原来的容量 + (原来的容量 / 2)取整] int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); // 获取最终扩容值newCapacity:默认扩容值 与 传入的容量minCapacity 中的最大的扩容值 if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 扩容(根据新的扩容值newCapacity,构造新的数组,并将旧的数组按序拷贝到新数组中,并取代旧的数组elementData) elementData = Arrays.copyOf(elementData, newCapacity); } ```
逻辑流程
- 校验是否需要扩容(以当前数组列表中元素个数size加1来判断)
- 计算数组列扩容后值capacity
- 校验数组列表是否为空,是则返回 10 和 size+1 中最小的值
- 否则返回 size+1 值
- Tips:size为数组列表中实际的元素数量
- 确定是否需要扩容,若需要则进行扩容,否则返回
- 判断计算后的扩容值capacity是否大于数组列表本身的容量
- 不是,则直接返回
- 否则,则执行扩容操作
- 执行扩容操作
- 获取默认扩容值
- 公式:原来的容量 + (原来的容量 / 2)取整
- 获取最终扩容值newCapacity
- 默认扩容值 与 计算后扩容值capacity 中的最大值
- 进行扩容
- 根据新的扩容值newCapacity
- 构造新的数组
- 并将旧的数组按序拷贝到新数组中
- 并取代旧的数组(elementData)
- 获取默认扩容值
- 计算数组列扩容后值capacity
- 容量足够或已扩容的情况下,将元素插入到数组列表(elementData)中
- 返回成功