ensureCapacity用于提前分配足够容量以避免多次自动扩容;适用于已知元素数量且需频繁添加的场景,如批量处理5000条日志或拼接1000字段JSON;也适用于高频小批量但总规模可控的循环添加。

在 Java 中,ensureCapacity 是 ArrayList 和 StringBuilder 等动态扩容容器提供的方法,用于**提前申请足够容量,避免后续多次自动扩容带来的性能开销**。它不常用,但在特定场景下能带来明显优化。
已知元素数量且需频繁添加的场景
当业务逻辑能预估最终集合或字符串的大致大小时,比如读取固定行数的文件、批量处理已知数量的 DTO、拼接 N 个 SQL 参数,手动调用 ensureCapacity 可一次性分配好空间,跳过中间多次扩容(如从 10→20→40→80 的倍增过程)。
- 例如:处理 5000 条日志记录,初始化
ArrayList<Log> list = new ArrayList<>();后立即执行list.ensureCapacity(5000); - 再比如构建含 1000 个字段的 JSON 字符串,用
StringBuilder sb = new StringBuilder(); sb.ensureCapacity(20000);预留足够字符空间
高频小批量 add 但总规模可控的循环场景
某些 for 循环中每次只 add 一个元素,但循环次数确定(如 for (int i = 0; i ensureCapacity 能消除扩容判断和数组复制的开销。
- 注意:若循环次数极小(如
- 对比直接使用带参构造器(如
new ArrayList(initialCapacity)),ensureCapacity更适合“已有实例、后期补救”的情况
避免并发写入时因扩容引发的临时竞争(非线程安全前提下)
虽然 ArrayList 和 StringBuilder 本身不支持并发修改,但在单线程中若存在多个逻辑块先后向同一实例添加数据,且各自无法控制对方行为,提前预留足量空间可减少扩容发生时机,间接降低因扩容导致的意外状态变化(如迭代器失效、引用地址变更等)。
- 典型例子:一个工具方法接收
StringBuilder作为参数,内部会追加一段内容;调用方在传入前先确保容量充足,避免工具方法执行中触发扩容影响后续操作 - 这不是线程安全方案,但有助于提升单线程组合调用的可预测性
不复杂但容易忽略——只要你知道最终要装多少,又不想让 JVM 多跑几趟扩容逻辑,ensureCapacity 就是个轻量有效的优化点。

















