Collections.fill用于统一赋值、Collections.copy用于逐位覆盖,二者均要求目标列表预先具备确定长度且不自动扩容;fill适合初始化默认值,copy适合安全复用容器;需避免空列表操作、LinkedList低效使用及类型不匹配等问题。

Collections.fill 和 Collections.copy 都是 Java 中用于批量操作 List 的静态工具方法,但用途截然不同:fill 是“统一赋值”,copy 是“逐位覆盖”,二者都要求目标列表已具备确定长度,不能自动扩容。它们在变量初始化阶段特别有用,比如预设缓存、构建测试数据、复用对象池等场景。
fill 适合初始化固定长度的默认值
它只替换已有位置上的元素,不新增、不扩容。所以必须先让列表有“槽位”。
- 正确做法:用 Collections.nCopies(n, null) 创建含 n 个占位元素的列表,再 fill
- 或用 Arrays.asList(new String[n]),数组长度即 list 长度,天然支持 fill
- 错误写法:new ArrayList<>().fill(...) —— ArrayList 没有实例方法 fill,且空列表无索引可操作
- 注意引用共享:填 new StringBuilder() 会导致所有位置指向同一个对象,修改一处全变;填 "hello" 或 42 则安全
copy 用于安全复用目标容器
它把源列表内容按顺序复制到目标列表对应索引位置,不改变目标列表长度,也不追加元素。
- 目标列表大小必须 ≥ 源列表,否则抛 IndexOutOfBoundsException
- 常用初始化方式:new ArrayList<>(Collections.nCopies(src.size(), null))
- 和 addAll() 不同:copy 是覆盖,addAll 是追加;copy 不改变目标结构,适合循环复用同一 list 实例
- 避免用 Arrays.asList(new String[5]) 作目标——它不支持 set 以外的修改,copy 可能失败
组合使用提升初始化效率
实际开发中,fill 和 copy 常配合使用,尤其在需要“重置+填充”或“模板化构造”的场景。
- 例如:定义一个 100 元素的缓冲区 list,每次处理前用 fill 清空为 null 或默认值,处理时用 copy 加载新批次数据
- 又如:用 fill 快速生成全 "N/A" 的结果列表,再对特定下标用 set 单独修正
- 搭配 subList(from, to).fill(x) 可实现局部填充(注意 subList 是原 list 的视图,fill 会同步生效)
别踩这些初始化坑
两个方法都依赖“列表已就位”,但新手常忽略前置条件。
- 空 ArrayList 调 fill → 无声失败:list 仍是空的,因为没索引可写
- 目标 list 太小调 copy → 运行时报错,不是编译错误,容易漏测
- 用 LinkedList 调 fill → 性能暴跌:get(i) 是 O(n),整体变成 O(n²),应只用于 ArrayList 或数组-backed 列表
- 泛型类型不匹配 → 编译失败:往 List<Integer> 里 fill("abc") 直接过不了编译

















