最高效的方式是构造时直接传入预期容量。例如 new arraylist(100) 预分配空间,避免多次扩容复制;避免先空参构造再 ensurecapacity;容量应贴近真实规模,既不过小导致频繁扩容,也不过大浪费内存;从已知大小集合初始化可自动适配容量。

直接在构造时传入预期容量,是最高效的方式。这样能避免后续扩容带来的数组复制开销。
用带初始容量的构造方法
这是最标准、最推荐的做法。ArrayList 内部基于 Object[] 数组,如果提前知道大概要存多少元素,就一次性分配足够空间:
-
正确写法:
new ArrayList<string>(100);</string>—— 预分配 100 个元素的空间 - 底层会创建一个长度为 100 的 Object[],后续 add() 直接填入,直到第 101 个才触发扩容
- 如果实际只加了 80 个,也没关系,空间稍有冗余但无性能损失;如果加到 150 个,只会扩容一次(从 100 → 150 → 225,按 1.5 倍增长)
别用空参构造后调用 ensureCapacity
虽然语义上看似等价,但多了一次无意义的初始化:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
不推荐:
ArrayList<string> list = new ArrayList(); list.ensureCapacity(100);</string> - 这会先创建默认大小为 10 的数组,再调用
ensureCapacity才扩容——多一次数组分配和复制 - 除非你无法在构造时确定容量(比如容量依赖运行时计算),否则没必要绕这个弯
容量值别过度预估,也别吝啬
初始容量不是越大越好,也不是越小越省,关键是“贴近真实使用规模”:
- 如果明确知道要放 5000 个对象,设成 5000 比设成 10 或 10000 更合理
- 设得太小(如 10)→ 频繁扩容(10→15→22→33→49→73…),大量复制浪费 CPU 和内存带宽
- 设得太大(如 100 万)→ 浪费堆内存,尤其对象生命周期短时,还可能引发 GC 压力
- 对不确定场景,可结合业务经验值(如分页查 20 条、日志缓冲通常 1024)、或用
Collection#size()(如传入的是已知大小的集合)
从已有集合初始化时自动适配
如果数据源本身可预知大小(比如另一个 List、Set、数组),优先用对应构造器:
-
new ArrayList(otherList);→ 内部会调用otherList.size()作为初始容量 -
new ArrayList(Arrays.asList(arr));→ 同样基于 arr.length 分配空间 - 这种写法简洁且零额外开销,比手动 new + for-loop add 高效得多
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










