调用 ensurecapacity 仅在批量插入前预先设置容量时有效,可避免多次扩容复制;若已扩容或边添加边调用则无效,构造时指定初始容量效果等同且更高效。

如果明确知道要插入大量元素,调用 ensureCapacity 可以避免多次自动扩容带来的数组复制开销,但实际效果取决于插入方式和初始容量设置是否合理。
什么时候调用 ensureCapacity 才有效
它只在插入前预先分配足够大的底层数组,后续 add 操作不再触发扩容。但如果已经发生过扩容,再调用它就只是“锦上添花”,无法回收已分配的多余空间。
- 最佳时机:创建 ArrayList 后、批量插入前立即调用
- 无效场景:边 add 边 ensureCapacity,或扩容已发生多次后再调用
- 注意:构造时传入初始容量(如
new ArrayList(1000))效果等同于后续调用ensureCapacity(1000)
ensureCapacity 和构造参数的区别
两者本质相同,都是设置内部数组的最小长度。构造函数里的容量会直接用于初始化数组;ensureCapacity 则比较当前数组长度与目标值,只在不足时扩容。
-
new ArrayList(500)→ 底层数组长度为 500 -
new ArrayList().ensureCapacity(500)→ 效果一样,但多一次方法调用开销 - 若已 add 了 200 个元素(此时数组可能已扩容到 256),再
ensureCapacity(500)→ 数组扩到 500
批量插入时的推荐写法
单纯调用 ensureCapacity 不等于性能提升,关键是要配合一次性插入或预知总量的操作模式。
- 已知总数:先
ensureCapacity(totalSize),再循环add或用addAll - 读取文件/数据库后插入:先统计条数,再初始化容量,最后批量填充
- 避免误区:对每个
add都调用ensureCapacity,反而增加方法调用开销
扩容机制与实际影响
ArrayList 默认扩容 1.5 倍(JDK 17+),频繁扩容会引发多次 Arrays.copyOf,复制旧数组内容。假设从默认 10 容量开始加 1000 个元素,约触发 7~8 次扩容,复制总量超 3000 元素次。
- 提前设容量为 1000 → 0 次扩容,0 次复制
- 设为 1200 → 仍 0 次扩容,且预留缓冲,适合不确定是否略超的情况
- 设太大(如 100 万)→ 浪费内存,尤其元素少时
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











