Java集合拷贝分浅拷贝和深拷贝:浅拷贝仅复制容器引用,适用于不可变元素;深拷贝需递归复制元素,适用于可变对象或嵌套结构,常用方式包括手动clone、序列化和JSON工具。

Java 中集合类的拷贝,关键看元素是否可变、嵌套结构是否复杂。浅拷贝适合元素不可变(如 String、Integer)或仅需单层隔离;深拷贝才真正切断所有引用链,适用于含自定义对象、嵌套集合等场景。
集合浅拷贝:复制容器,不复制元素
本质是新建一个集合容器,把原集合中元素的引用逐个添加进去。新旧集合互不影响,但若元素是可变对象(如 StringBuilder、自定义类),修改该元素内容仍会同步体现。
-
ArrayList / LinkedList 构造方法:最常用、简洁、高效
List<string> original = Arrays.asList("a", "b");<br>List<string> copy = new ArrayList(original);</string></string> -
Stream.collect():函数式写法,语义清晰
Listcopy = original.stream().collect(Collectors.toList()); - Arrays.asList() 不适用:它返回的是固定大小的内部 List,不是独立副本
集合深拷贝:元素也要“新生”
当集合里存的是可变对象(比如 Person、Address)或嵌套集合(如 List>),必须让每个元素也生成独立副本,否则只是“假深拷贝”。
-
手动遍历 + 元素 clone():要求元素类实现 Cloneable 并重写 clone()
List<person> deepCopy = original.stream()<br> .map(p -> (Person) p.clone())<br> .collect(Collectors.toList());</person>
-
序列化方式(通用但有约束):所有元素及嵌套类型都必须实现 Serializable
用 ByteArrayOutputStream + ObjectOutputStream 序列化再反序列化,能递归复制整个对象图 -
JSON 工具(绕过 Serializable):如 Jackson 或 Gson
将集合转成 JSON 字符串再解析回对象,天然支持深拷贝,但注意:类型信息可能丢失(如 HashMap 变成 LinkedHashMap)、不支持循环引用、无 transient 控制
常见误区与提醒
别以为 new ArrayList(list) 就万事大吉——它只对 String、LocalDate 等不可变元素安全;一旦里面是 new Person("张三"),两个集合里的 Person 实例仍是同一个对象。
- 数组不能直接用构造方法拷贝:要用
Arrays.copyOf()或System.arraycopy() - Set、Map 同理:HashSet 构造器可浅拷贝,但 Map 的 value 是对象时,需单独深拷贝 value
- 第三方工具如 Apache Commons Lang 的
SerializationUtils.clone()写法简单,但性能低、跳过 transient 字段、要求全可序列化
选哪种方式,取决于你的集合结构和运行环境。简单场景用构造方法就够了;复杂嵌套又不想改代码,序列化或 JSON 是稳妥选择;追求性能和可控性,就手动 clone 或构造新实例。











