预设容量能显著提升 arraylist 批量插入性能。应在预知元素总数且首次 add 前调用 ensurecapacity 或使用带初始容量的构造器;过度设置会浪费内存,小数据无需干预。

在已知要插入大量元素时,调用 ensureCapacity 能显著减少扩容次数,从而避免反复创建新数组、复制旧数据的开销,提升插入性能。
什么时候该用 ensureCapacity
适用于批量插入前能预估元素总数的场景,比如从数据库查出 5 万条记录、读取一个固定大小的日志文件、或接收一批接口返回的数据。
- 如果完全不确定数据量,用它意义不大,甚至可能浪费内存
- 如果只插几个或几十个元素,扩容开销几乎可忽略,无需干预
- 最佳时机是 在第一次 add 之前 调用,越早设定越有效
两种等效写法,推荐构造器初始化
效果相同,但带初始容量的构造器更简洁、更常用:
-
推荐:直接在创建时指定容量 ——
new ArrayList(expectedSize) - 手动调用:
list.ensureCapacity(expectedSize)(适合已有 list 实例需复用的场景)
两者底层都确保内部数组长度 ≥ expectedSize,后续 add 不会触发扩容,直到 size 超过该值。
扩容代价到底有多大
每次扩容不是简单“加几个格子”,而是:
- 申请一块新内存(通常是原容量的 1.5 倍)
- 用
System.arraycopy把所有已有元素逐个拷贝过去 - 原数组变成垃圾,等待 GC 回收
插入 10 万条数据时,无预设容量可能触发约 17 次扩容,耗时翻倍;预设后扩容次数为 0,耗时减半。
注意别过度优化
ensureCapacity 不是“越大越好”:
- 设成 100 万但只存 1 千个元素,会白白占用近 8MB 内存(Object[] 每个引用占 8 字节)
- JDK 默认初始容量是 10,首次 add 就扩容到 10,所以空构造器对小数据完全够用
- 若数据规模波动大,可结合业务上限 + 10%~20% 余量来设,不必死磕精确值
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











