在java中,我们如果想要对引用类型的集合进行深拷贝。有一种方式,就是调用SerializationUtils
Apache Commons Lang (SerializationUtils
)
Apache Commons Lang 提供了 SerializationUtils
类,可以利用 Java 的序列化机制来进行集合及其元素的深拷贝。通过将集合进行序列化和反序列化,达到深拷贝的效果。
List<Person> originalList = new ArrayList<>();originalList.add(new Person("Alice"));originalList.add(new Person("Bob"));List<Person> copiedList = SerializationUtils.clone((ArrayList<Person>) originalList);System.out.println("Original List: " + originalList);System.out.println("Copied List: " + copiedList);// 修改拷贝中的对象,验证深拷贝copiedList.get(0).name = "Charlie";System.out.println("Original List: " + originalList);System.out.println("Copied List: " + copiedList);
结果:
Original List: [Person{name='Alice'}, Person{name='Bob'}]
Copied List: [Person{name='Alice'}, Person{name='Bob'}]
Original List: [Person{name='Alice'}, Person{name='Bob'}]
Copied List: [Person{name='Charlie'}, Person{name='Bob'}]
注意: 这种方法要求集合及其元素实现
Serializable
接口,因此适用于所有支持序列化的对象。
如果你希望用其他方法对集合进行深拷贝,可以选择以下几种方式:
除了SerializationUtils和以下的
ObjectMapper
,都是需要手动遍历添加引用类型对象,尽管重写了clone()方法
- Google Guava (
Lists.newArrayList()
):通过手动遍历和元素复制来实现深拷贝。 - Jackson (
ObjectMapper
):通过序列化和反序列化的方式进行深拷贝。 - Spring Framework (
BeanUtils.copyProperties()
):适用于 JavaBean 对象,可以在循环中手动深拷贝。 - Java 8
Cloneable
接口结合流式操作:如果对象实现了Cloneable
,可以利用clone()
方法结合 Stream API 进行深拷贝。
这里只举一个例子:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;public class DeepCopyExample {public static void main(String[] args) throws CloneNotSupportedException {List<Person> originalList = new ArrayList<>();originalList.add(new Person("Alice", 30));originalList.add(new Person("Bob", 25));// 使用 Java 8 Stream 和 Cloneable 实现深拷贝List<Person> deepCopy = originalList.stream().map(person -> person.clone()) // 假设 Person 实现了 Cloneable.collect(Collectors.toList());// 输出检查System.out.println(originalList);System.out.println(deepCopy);}
}