Collections.nCopies返回的是共享引用、仅存element和n的不可变虚拟列表CopiesList,内存恒定约40字节,无对象副本与堆分配,get(i)直接返回同一实例,适用于只读占位场景。

它不真存 N 个对象,只存一份引用和数量,内存恒定约 24 字节——无论你要 10 行还是 100 万行占位符,开销几乎一样。
为什么叫“虚拟列表”而不是真列表
Collections.nCopies(n, obj) 返回的是 CopiesList(私有静态内部类),不是 ArrayList 或 LinkedList。它内部只有三个字段:element(被复用的对象引用)、n(逻辑长度)、hashCode(懒计算)。没有数组、没有对象副本、不分配堆内存。
- 调用
get(i)时直接返回element,不新建对象,也不查表 -
size()就是返回n,无遍历成本 - 所有“位置”都指向同一个
obj实例——这不是 bug,是设计目标
在默认占位符场景下的真实收益
比如 RecyclerView 需要 500 行「暂无数据」提示,或后台服务预设 10 万条统一状态记录:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用循环 new ArrayList() + add:分配 10 万个引用空间,至少 800KB(64 位 JVM,每个引用 8 字节)
- 用
Collections.nCopies(100_000, "PENDING"):仅创建一个轻量对象,内存 ≈ 24 字节(对象头)+ 两个 long 字段 ≈ 40 字节以内 - GC 压力归零:没新对象诞生,不触发 Young GC
安全使用的前提条件
占位符必须是不可变值,否则共享引用会引发意外副作用:
立即学习“Java免费学习笔记(深入)”;
- ✅ 安全类型:
"LOADING"、Integer.valueOf(0)、Boolean.FALSE、枚举常量 - ❌ 危险类型:
new ArrayList()、new StringBuilder()、自定义可变 DTO —— 修改任一位置等于改全部 - ⚠️ null 本身合法:
Collections.nCopies(100, null)有效,但后续使用需判空
如何无缝接入现有逻辑
它实现 List 接口,能直接用于大多数只读上下文:
- 传给
Collections.frequency(list, "PENDING") - 作为
Arrays.asList(...)的替代,避免临时数组 - 配合 Stream 操作:
list.stream().map(...).collect(...) - UI 层绑定(如 JavaFX ObservableList 包装、Swing TableModel)只要不调用
add/set就完全兼容

















