collections.addall() 比先转集合再 addall 更快,因其跳过 arrays.aslist() 包装、避免 iterator 开销、预知容量减少扩容、失败立即暴露且语义清晰;仅适用于初始化批量添加。

直接用 Collections.addAll() 处理变长参数,比先转成集合再调用 collection.addAll() 更快,核心在于跳过中间对象、减少间接调用、避免冗余扩容。
绕过 Arrays.asList() 这层包装
写 list.addAll(Arrays.asList("a", "b", "c")) 时,JVM 先创建一个 Integer[](或对应类型数组),再用 Arrays.asList() 包装成一个只读代理 List——这个 List 背后仍是原数组,但对外暴露的是 Iterator 接口。而 Collections.addAll(list, "a", "b", "c") 的 varargs 参数直接生成数组,内部遍历就是普通 for 循环索引访问,不经过 Iterator 的 hasNext()/next() 方法调用,也没有额外的 List 实例开销。
一次预估容量,避免反复扩容
ArrayList 的 add() 每次都要检查当前容量是否足够,不够就扩容(复制整个底层数组)。对百万级初始化,逐个 add 可能触发十几次扩容;而 Collections.addAll() 在开始前已知元素个数(varargs 数组长度固定),多数 JDK 实现会在首次写入前一次性确保足够容量——哪怕没显式指定初始容量,底层也能更早完成扩容决策。
语义清晰,错误更早暴露
如果目标 list 是不可修改的(比如被 Collections.unmodifiableList() 包装过),collection.addAll(...) 会在循环中第 N 次 add 时才抛 UnsupportedOperationException;而 Collections.addAll() 是单次调用,失败立刻发生,定位更准。同时,一行写完初始化,不漏边界、不误索引,逻辑集中不易出错。
适用边界很明确
它只适合初始化阶段批量塞入已知数量的字面量或数组元素;不适合边判断边添加的场景(比如 if 成立才加某个元素),那种情况仍需手动 add。另外注意:它不能替代 list.addAll(otherCollection)——后者专用于合并另一个 Collection 实例,语义和性能都更自然。











