预设初始容量是优化ArrayList大容量数据传输性能的关键,可避免反复扩容导致的数组复制开销;需区分size()与capacity,万级以上数据建议预设并留5%~10%余量,或用ensureCapacity提前扩容。

Java 中 ArrayList 处理大容量数据传输,关键不是“传数据”本身,而是避免在填充过程中反复扩容——这才是性能卡点。真正耗时的不是 add 操作,而是背后隐式的数组复制。
预设足够初始容量是最直接有效的手段
如果已知要装多少条数据,创建时就指定容量,一步到位:
- 比如预计插入 80 万条记录:new ArrayList(800000)
- 若规模可估算,建议留 5%~10% 余量(如预估 92 万,设 97 万),既防错估,又不浪费内存
- 注意:size() 返回当前元素个数;capacity 是 elementData.length,二者不同,别混淆
无法构造时,用 ensureCapacity 提前“划好地盘”
适用于运行时才确定规模、但批量添加前能预估的情形:
- 在 for 循环 add 前调用一次:list.ensureCapacity(1000000)
- 它只在当前容量不足时才真正扩容,否则开销几乎为零
- 比在循环里反复判断是否该扩容更安全、更高效
避开扩容优化覆盖不了的操作模式
预设容量只加速尾部添加(add(E))和随机访问(get(i))。以下操作仍慢,需另寻方案:
立即学习“Java免费学习笔记(深入)”;
- 避免在循环中用 add(index, e) 或 remove(index) 插入/删除中间元素——每次都要移动后续所有元素
- 批量加多个元素,优先用 addAll(collection),它内部会做容量预判和批量复制
- 若业务大量涉及中间增删,ArrayList 本身就不合适,应考虑 LinkedList 或重构逻辑(如先收集再一次性组装)
结合实际规模做合理取舍
优化不是越激进越好,要看场景:
- 几百条以内:默认构造更简洁,没必要预设
- 万级及以上、写入高频且规模稳定(如日志缓冲、DB 批量导出):强烈建议预设,实测提速 40%~60%,扩容次数归零
- 规模波动大又不敢错估太多:可先设保守值,再结合 JVM 监控(GC 频率、堆内存走势)反向调整


















