Collections.nCopies() 返回逻辑上含n个相同元素的只读List视图,内存恒定、不存实际副本,适用于默认值填充等场景,但不可修改且慎用于可变对象。

Collections.nCopies() 是 Java 中一个轻量级工具方法,它不真正创建海量元素的集合,而是返回一个**逻辑上包含 n 个相同元素的只读 List 视图**。它的核心价值在于“以常量内存开销模拟大规模重复集合”,特别适合配置、默认值填充、测试数据生成等场景。
理解 nCopies() 的内存节省原理
它返回的是 CopiesList(私有静态内部类),内部只保存三个字段:element(被复制的对象引用)、n(数量)、hashCode(懒计算)。无论 n 是 100 还是 100 万,内存占用几乎不变——没有实际存储 n 个对象副本,只是“假装有”。
注意:它不是 ArrayList 或 LinkedList,不支持 add/remove/set 等修改操作,调用会直接抛 UnsupportedOperationException。
典型适用场景与写法
- 初始化固定长度的默认值列表:比如为 1000 个用户设置统一的初始状态
List<String> defaultRoles = Collections.nCopies(1000, "USER");
- 配合 Stream 或 Arrays.asList 做轻量构造:避免手动循环 new ArrayList
List<Integer> zeros = Collections.nCopies(1_000_000, 0); // 占用 ~24 字节,非 4MB
- 作为不可变占位符参与运算:例如传给 Collections.frequency()、或用于 Collections.binarySearch(需保证元素可比较)
必须避开的坑
- 不要对可变对象使用:如果传入的是 new ArrayList<>() 或自定义可变对象,所有“逻辑位置”都指向同一实例,修改任一位置等于修改全部
-
不要试图转成 ArrayList 后再修改:虽然
new ArrayList(nCopies(...))能创建可变副本,但此时已失去内存优势,且容易误以为原视图可变 -
注意泛型擦除下的类型安全:
Collections.nCopies(3, null)返回List<Object>,若需List<String>,应显式指定类型或用String.class.cast(null)(谨慎)
替代方案对比(何时不该用)
如果需要: – 随机访问性能极致(nCopies 的 get(i) 是 O(1),没问题); – 元素本身是不可变值(如 String、Integer、enum); – 不需要结构修改或迭代中动态变更。 那它就是最优解。
否则,考虑:
// 需要后续 add?→ 用 ArrayList + 构造器
List<String> list = new ArrayList<>(Collections.nCopies(1000, "A"));
// 需要原始类型数组?→ 直接 new int[1000]

















