ArrayList扩容由grow()方法自动完成,触发条件是添加元素前检查size+1>elementData.length;新容量按旧容量+旧容量>>1(即1.5倍)计算,初始10→15→22→33;扩容前校验最小需求及Integer.MAX_VALUE-8边界;最终通过Arrays.copyOf复制元素并更新引用。

容量不足时,ArrayList 会触发 grow() 方法完成扩容,整个过程是自动、可控且有边界保护的。
扩容的触发时机
每次调用 add(E e) 或 addAll(...) 等添加方法时,都会先检查:if (size + 1 > elementData.length)
即当前元素个数加 1 超过数组长度,就判定为容量不足,立即准备扩容。
新容量怎么算出来的
核心公式是:
新容量 = 旧容量 + (旧容量 >> 1)
也就是旧容量的 1.5 倍(右移 1 位等价于整除 2,向下取整)。
- 初始容量为 10 → 首次扩容后为 15(10 + 5)
- 容量为 15 → 下次扩容为 22(15 + 7)
- 容量为 22 → 扩容为 33(22 + 11)
这个计算不是固定倍率,而是基于位运算,效率高、无浮点误差。
扩容前的关键校验
算出新容量后,并不直接使用,还要两步兜底判断:
- 如果新容量仍小于实际所需最小容量(比如一次 addAll 20 个元素,而当前为空),则直接设为所需最小值
- 如果新容量超过
Integer.MAX_VALUE - 8(JVM 数组长度上限),则调用hugeCapacity(),最终可能设为Integer.MAX_VALUE
真正扩容的操作
最后一步是实质性的内存操作:elementData = Arrays.copyOf(elementData, newCapacity);
这行代码会:
- 分配一块新内存,大小为
newCapacity - 把原数组所有元素逐个复制过去(时间复杂度 O(n))
- 将
elementData引用指向新数组
旧数组随后被 GC 回收,整个扩容完成。











