直接指定 arraylist 的初始容量是最简单有效的性能优化手段,因其避免扩容时的数组重建与元素复制开销,尤其适用于已知数据规模的批量添加场景。

直接指定 ArrayList 的初始容量,是最简单、最有效的集合性能优化手段之一。它不改变逻辑,也不增加复杂度,却能显著减少扩容次数和内存复制开销——尤其在批量添加已知规模数据时。
为什么提前设 initialCapacity 能提升性能
ArrayList 底层是数组,扩容不是“伸展”,而是“重建”:每次扩容都要创建新数组、用 System.arraycopy() 或 Arrays.copyOf() 复制全部已有元素。这个过程时间复杂度是 O(n),且会触发额外的 GC 压力。
默认构造器(new ArrayList())使用空数组,首次 add 时才初始化为长度 10;之后每满即扩,按 1.5 倍增长(如 10 → 15 → 22 → 33 → 49…)。若你要存 1000 条数据,不预设容量会触发约 7 次扩容,复制元素累计超 3000 次;而设 initialCapacity = 1000,一次到位,零扩容。
怎么合理估算 initialCapacity
关键不是精确到个位数,而是避免严重低估。只要不低于实际元素数量,就基本杜绝中途扩容。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 查数据库列表:用
SELECT COUNT(*)预估总数,或直接用分页 size(如limit 50就设 50~60) - 接收 HTTP 请求参数:看前端传来的数组长度(如
request.getParams().size()),再加 10% 缓冲 - 固定业务场景:订单明细最多 200 行、日志条目单次不超过 5000 条 → 直接写死对应值
- 不确定但有上限:比如“最多导入 1 万行 Excel”,就设
10000,比反复扩容便宜得多
代码写法与常见误区
推荐写法清晰明确:
List<order> orders = new ArrayList(estimatedCount);</order>
注意避开这些坑:
- 别用
new ArrayList().ensureCapacity(n)—— 这只是“建议扩容”,不立即分配内存,add 时仍可能触发首次扩容 - 别传 0 或负数:虽然不报错,但等于白设;传 1 也无意义,很快又得扩
- 别盲目设极大值(如 100 万):浪费堆内存,可能引发 OOM,尤其在线程多、实例多的场景
- 如果后续要
addAll(collection),优先用带参构造:new ArrayList(collection),它内部会调用collection.size()自动设容量
配合其他操作进一步提效
光设容量还不够,搭配使用更省资源:
- 确定不再增删时,调用
trimToSize()释放多余空间(适合长生命周期对象) - 循环添加前,确认没用错方法:避免在 for 循环里反复调用
list.add(...)却没预估,尤其是嵌套查询场景 - 高并发写入?
ArrayList本身非线程安全,不要靠扩容优化掩盖线程问题;该换CopyOnWriteArrayList或加锁就加锁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










