预设 ArrayList 初始容量可避免频繁扩容拷贝,提升性能;已知数量用 new ArrayList(n),估算则加5%~10%余量;无法构造时可用 ensureCapacity() 预占空间;该优化仅对尾部添加有效,随机增删应换数据结构。

核心就一条:提前告诉 ArrayList “我要存多少”,让它一次性把底层数组空间准备好,避免边加边扩、反复拷贝。
预设初始容量最直接有效
默认构造器容量只有 10,插第 11 个元素就触发第一次扩容(→15),之后按 1.5 倍增长。10 万条数据可能扩 17 次,每次都是全量复制+新内存分配。
- 已知确切数量:用 new ArrayList(n),比如
new ArrayList(100000) - 数量可估算:取预估值 + 5%~10% 余量,例如预估 9500,设 10000 即可
- 别混淆 size() 和 capacity:size() 是当前元素个数;capacity 是底层数组长度,得靠
list.toArray().length或反射查,但通常不需要——预设对了,capacity 就够用
无法构造时用 ensureCapacity 预占空间
有些场景初始化时真不知道要加多少,但批量添加前能预估(比如读文件前知道行数、查数据库前知道结果集大小),这时就在循环 add 前调一次 ensureCapacity:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
-
list.ensureCapacity(10000);—— 它只在当前容量不足时才真正扩容,否则无开销 - 效果和构造函数一样,都是提前分配数组,不走 grow() 的判断逻辑
- 切记:只调一次,别在循环里反复调,那没意义
避开 ArrayList 不擅长的操作
预设容量只优化“尾部添加”,对中间插入/删除完全无效:
-
add(index, e)或remove(index)每次都要移动后续所有元素,O(n) 开销叠加 - 如果业务大量涉及随机位置增删,ArrayList 本身就不合适,应换 LinkedList、ArrayDeque(队列场景)或重构为批量处理+重建列表
- 批量加多个元素时,用
addAll(collection)而非循环add(),它内部会做容量预判和批量复制
结合实际权衡,不盲目堆容量
优化不是越大越好,要算账:
- 几百条以内数据:不预设也无所谓,代码更简洁
- 稳定大批量写入(如日志缓冲、ETL 导入):强烈建议预设,实测提速 40%~60%,扩容次数归零
- 规模波动大又不敢错估太多:先设保守值,再配合 JVM 监控(GC 频率、老年代占用)反向调整


















