跳转到主内容
极星编程网:以代码为星,赴技术山海!

怎么通过 Collections.nCopies() 快速初始化一个充满重复对象的列表

Collections.nCopies() 返回只读视图,底层共享引用,适用于不可变类型或只读场景;若需独立可变对象,应使用 Stream.generate() 或循环构造。 用
Collections.nCopies()
创建不可变重复列表时,别直接当普通
List
用 它返回的是只读视图,底层共享同一引用 —— 所以如果你传入的是可变对象(比如
new ArrayList()
),所有位置都指向同一个实例。修改其中任意一个,整个列表“全跟着变”。 正确场景:初始化
String
、
Integer
等不可变类型,或仅作只读用途 错误写法:
List> list = Collections.nCopies(3, new ArrayList())
→ 三个元素其实是同一个
ArrayList
实例 想每个都是独立对象?得配合
Stream.generate()
或循环构造,不能只靠
nCopies
Collections.nCopies()
的参数边界和性能表现 第一个参数是数量,必须 ≥ 0;负数会抛
IllegalArgumentException
;第二个参数是填入的元素,可以为
null
(生成的列表里对应位置就是
null
)。 时间复杂度 O(1),不真正创建
n
个对象,只是逻辑上“看起来有 n 份” 内存占用极小,适合做大容量只读占位,比如初始化 10 万长度的默认值列表 但调用
get(i)
是 O(1),而
set(i, x)
会直接抛
UnsupportedOperationException
替代方案:需要可变且独立副本时怎么写 如果目标是“n 个互不影响的可变对象”,
nCopies
不适用,必须显式构造。 Java 8+ 推荐:
List list = Stream.generate(MyObj::new).limit(n).collect(Collectors.toList())
传统写法:
List list = new ArrayList(n); for (int i = 0; i
注意:不要写成
Collections.nCopies(n, new MyObj())
—— 这仍是单实例复用,不是复制 常见报错:为什么
add()
或
remove()
会失败 因为
Collections.nCopies()
返回的是
java.util.Collections$CopiesList
,内部没有实现结构性修改方法。 触发异常:
UnsupportedOperationException
,错误信息类似
"add" not supported
哪怕你把它赋给
List
接口变量,也不改变其不可变本质 如果后续要增删,必须转成可变实现:
new ArrayList(Collections.nCopies(n, "x"))
—— 但注意这会真实复制引用(不是深拷贝) 实际用的时候,先问自己一句:这个列表之后会不会被修改?每个元素是否必须彼此隔离?答案决定你是用
nCopies
、
Stream.generate
,还是老老实实写循环。

相关文章