ensureCapacity 不会自动扩容,而是预分配空间以减少add时的数组复制开销;它只在当前容量小于minCapacity时扩容至max(原容量×1.5, minCapacity),不改变size,适用于已知元素总数的批量插入场景。

ArrayList 的 ensureCapacity 不会自动扩容,它只是提前“预留”足够容量,避免后续 add 操作频繁触发内部数组复制,从而提升性能。
ensureCapacity 的作用是预分配空间
ArrayList 底层用 Object[] 存储元素,默认初始容量是 10。每次添加元素超过当前容量时,会创建新数组(通常是原容量 1.5 倍),再把老数据拷贝过去——这个复制过程耗时,尤其数据量大时明显。
ensureCapacity(int minCapacity) 的作用就是:在大量插入前,主动告诉 ArrayList “我至少需要这么多空间”,让它一次性扩容到位,减少甚至消除中间多次扩容。
- 它只在当前容量 小于 minCapacity 时才真正扩容;否则什么也不做
- 扩容后容量 = max(原容量 × 1.5, minCapacity),但不会低于 minCapacity
- 它不改变 size(实际元素个数),只影响内部数组长度(capacity)
什么时候调用最有效
适合已知最终元素数量的场景,比如批量初始化、读取固定大小的数据集。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
- 从数据库查出 5000 条记录,准备全塞进 ArrayList:先调
list.ensureCapacity(5000) - 解析一个 JSON 数组,知道有 1000 个对象:构造完 list 就立即 ensureCapacity(1000)
- 循环 add 之前调用,而不是边 add 边调(后者失去意义)
对比直接构造指定容量更推荐
虽然 ensureCapacity 有用,但更简洁的方式是在创建时就指定初始容量:
-
new ArrayList(5000)—— 效果等同于 new + ensureCapacity(5000) - 构造器内部也调了 ensureCapacity,且语义更清晰、代码更少
- 如果后续 size 超过初始容量,仍会正常扩容,无需担心“设小了”
注意 avoid 的误区
ensureCapacity 不是“越大越好”,盲目设极大值会浪费内存:
- 设 capacity = 1000000,但只存 10 个元素 → 浪费大量堆空间
- 不确定数量时,别硬猜,用默认行为更稳妥
- 它对 get、set、remove 等操作无加速效果,只优化 add 过程中的扩容开销


















