JAVA 拷贝List 深拷贝

在进行Java编程时,我们经常会遇到需要复制一个List的情况。然而,List的复制并不是那么简单。如果我们想要创建一个新的List,并且这个新的List与原来的List具有相同的元素,但是在修改新的List时不会影响原来的List,我们就需要进行深拷贝。

什么是深拷贝

深拷贝是创建一个新的对象,复制原始对象的所有字段的值,并复制所有引用对象的复制。也就是说,深拷贝会递归地复制所有引用对象。

与深拷贝相对的是浅拷贝。浅拷贝只会复制对象的引用,而不会复制引用对象。这就意味着,如果我们对新对象所引用的对象进行修改,原始对象也会受到影响。

因此,如果我们需要在复制List时保持原有List与新List之间的互不影响,我们就需要进行深拷贝。

为什么需要深拷贝List

在Java中,List是一个非常常用的数据结构。我们经常会使用List来存储一系列对象,并对这些对象进行操作。然而,有时候我们需要将这些对象复制到一个新的List中,并对新的List进行操作,而不想影响原有的List。

举个例子,假设我们有一个List存储了学生对象,我们需要根据某种条件筛选出成绩优秀的学生,并将其放入一个新的List中。同时,我们希望在新的List中对学生信息进行修改时,不影响原有的List。

为了实现这个目标,我们就需要进行深拷贝。

实现深拷贝的方法

在Java中,有多种方法可以实现深拷贝。下面我们将介绍两种常用的方法。

方法一:使用构造函数

Java中的大多数类都有一个默认的构造函数,用于创建该类的对象。我们可以通过使用这个构造函数创建一个新的对象,并将原始对象的字段值赋给新对象。

下面是一个示例代码:

class Student {
    private String name;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 省略getter和setter方法
}

List<Student> originalList = new ArrayList<>();
originalList.add(new Student("Alice", 20));
originalList.add(new Student("Bob", 21));

List<Student> newList = new ArrayList<>();
for (Student student : originalList) {
    newList.add(new Student(student.getName(), student.getAge()));
}

上面的代码中,我们首先创建一个原始的List,其中包含两个Student对象。然后,我们创建一个新的List,并遍历原始List中的每个Student对象,通过调用Student对象的构造函数来创建新的Student对象,并将原始Student对象的字段值赋给新对象。

这样,我们就得到了一个新的List,其中包含与原始List相同的Student对象。

这种方法的好处是简单直观,容易理解和实现。但是,它需要我们手动创建新的对象,并将原始对象的字段值逐个赋给新对象的字段。如果对象的字段较多,这样的操作会比较繁琐。

方法二:使用序列化和反序列化

Java中的序列化和反序列化机制提供了一种更方便的方式来实现深拷贝。

序列化是将对象转换为字节流的过程,而反序列化是将字节流转换回对象的过程。通过将对象进行序列化,然后再将序列化后的字节流进行反序列化,我们就可以得到一个与原始对象完全相同的新对象。

下面是一个示例代码:

import java.io.*;

List<Student> originalList = new ArrayList<>();
originalList.add(new Student("Alice", 20));
originalList.add(new Student("Bob", 21));

List<Student> newList = null;
try {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream o