arraylist扩容由add触发,自动调用arrays.copyof(底层为system.arraycopy)实现1.5倍增长,初始容量10;可预设容量或调用ensurecapacity减少扩容次数。

Java 中 ArrayList 的扩容机制在底层确实依赖 Arrays.copyOf 来完成数组拷贝,但它的作用不是“使用”这个方法去手动扩容,而是 ArrayList 在内部自动调用它来实现容量增长。理解这个过程的关键在于:扩容是自动触发的,Arrays.copyOf 是 JDK 提供的高效封装,实际调用了 System.arraycopy(本地方法)。
扩容何时发生
当向 ArrayList 添加元素(如 add(E e))时,如果当前元素个数(size)等于底层数组长度(elementData.length),就会触发扩容:
- 默认初始容量为 10(JDK 17+ 仍保持该约定)
- 每次扩容为原容量的 1.5 倍(即
oldCapacity + oldCapacity >> 1) - 若计算后仍不够(例如指定初始容量很小,又批量添加大量数据),则直接扩到所需最小容量
Arrays.copyOf 如何参与扩容
ArrayList 在 grow(int minCapacity) 方法中调用 Arrays.copyOf,例如:
// 简化示意,非源码直抄
elementData = Arrays.copyOf(elementData, newCapacity);
这行代码实际等价于:
- 分配一个新数组,长度为
newCapacity - 将原
elementData中前size个有效元素复制过去(注意:不是整个旧数组,只复制已有元素) - 返回新数组引用,赋给
elementData
Arrays.copyOf 内部最终调用 System.arraycopy,这是 JVM 优化过的本地方法,比纯 Java 循环拷贝快得多。
为什么不用自己写 for 循环拷贝
手动遍历复制不仅效率低,还容易出错。而 Arrays.copyOf 封装了安全、高效的逻辑:
- 自动处理
null数组和负长度异常 - 对基本类型和引用类型都有专用重载(如
copyOf(int[], int)、copyOf(Object[], int)) - 支持截断(新长度小于原数组)或补
null(新长度更大) - 避免越界、空指针等常见问题
可干预扩容行为的实用方式
虽然不能也不应替换 Arrays.copyOf,但你可以合理影响扩容频率:
- 初始化时预估大小:
new ArrayList(1000),减少多次扩容开销 - 批量添加前调用
ensureCapacity(int minCapacity),主动预留空间 - 避免在循环中反复
add而不预设容量(尤其数据量大时)
这些做法让 Arrays.copyOf 更少被调用,从而提升性能。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











