Java中ArrayList扩容机制是按需自动增长,本质是创建更大新数组并复制元素;扩容发生在add前检查size+1>elementData.length时;新容量默认为旧容量1.5倍(oldCapacity + oldCapacity>>1),不足则取最小需容量;无参构造首次add才扩至10。

Java 中 ArrayList 的底层扩容机制,核心是“按需自动增长”,本质是用一个更大的新数组替换旧数组,并把原有元素复制过去。它不是实时平滑扩容,而是在容量真正不够时才触发一次复制操作。
扩容什么时候发生?
每次调用 add() 方法添加元素前,ArrayList 都会检查:
当前元素个数 + 1 是否超过底层数组长度(size + 1 > elementData.length)。
如果超了,就立刻进入扩容流程;否则直接存入,不涉及任何复制开销。
新容量怎么算?
扩容逻辑集中在 grow() 方法里,规则很明确:
- 默认新容量 = 旧容量 + 旧容量右移一位 → 即 旧容量 × 1.5(比如 10 → 15,15 → 22)
- 这个计算用的是位运算
oldCapacity + (oldCapacity >> 1),比除法更快 - 但如果计算出的新容量仍小于“实际需要的最小容量”(比如首次添加时要塞 20 个元素),就直接取所需最小值,不硬套 1.5 倍
初始容量有特殊处理
不同构造方式影响首次扩容行为:
- 无参构造 new ArrayList<>():JDK 1.8 起采用懒加载,elementData 初始指向空数组 {},第一次 add 才扩容到 10
- 指定容量 new ArrayList(5):直接创建长度为 5 的数组,后续扩容仍按 1.5 倍走
- 传入集合 new ArrayList(otherList):数组长度直接设为 otherList.size(),避免首轮冗余扩容
扩容过程做了什么?
不是原地扩展,而是三步原子操作:
立即学习“Java免费学习笔记(深入)”;
- 算出新容量
- 调用 Arrays.copyOf(elementData, newCapacity) 创建新数组并批量复制元素
- 用新数组替换原来的 elementData 引用
注意:复制是 O(n) 操作,但因扩容频率随容量增大而降低(10→15→22→33…),所以 add 的平均时间复杂度仍是分摊 O(1)。


















