最高效的方式是预估最终元素数量并直接传入构造参数,避免多次扩容;初始容量为10是通用折中值,扩容需新建数组并复制元素,开销大;设过大浪费内存,设过小导致频繁扩容;容量不等于大小,超出仍可自动扩容。

最高效的方式是:预估最终元素数量,直接传入该值作为构造参数,且不盲目放大。
明确初始容量的作用
ArrayList 默认初始容量是 10,但这是为通用小场景设计的折中值。它底层用数组存储,扩容时要新建数组、复制全部旧元素——这个过程开销不小。如果你清楚将放入约 800 个对象,却用 new ArrayList(),大概率会经历多次扩容(10 → 15 → 22 → 33 → 49 → …),徒增 CPU 和内存压力。
怎么算出“合适”的初始容量
不需要复杂公式,按实际业务数据来:
- 分页查询每页 30 条 → 初始容量设为 30 或 35 即可
- 日志聚合一批最多 2000 条记录 → 直接设 2000
- 从数据库查出确定数量的列表(如
SELECT COUNT(*)已知共 1276 条)→ 设 1276 或向上取整到 1300 - 完全无法预估(比如用户自由输入的临时列表)→ 保持默认,不强行优化
注意两个常见误区
一是容量不是越大越好。设成 10000 却只存 200 个元素,浪费内存;尤其在高并发或大量实例场景(如 Web 请求中每个 DTO 都 new 一个超大 ArrayList),容易引发 GC 压力。
二是别混淆“容量”和“大小”。初始容量只是底层数组长度,不影响 size() 返回值,也不限制后续 add() 次数——超出后仍会自动扩容,只是你主动避免了前几轮。
进阶技巧:运行时预留空间
如果元素是分批添加的(比如先加 500,再加 300),可在第一批前调用:
list.ensureCapacity(800);
这比构造时设 500 更灵活,也避免了第二批触发扩容。适用于已知总量但添加节奏不统一的场景。











