在 Java 中深拷贝 ArrayList

Rashmi Patidar 2021年4月29日
在 Java 中深拷贝 ArrayList

在 Java 语言中,如果要复制 ArrayList,可以有两种方法。进行深拷贝或浅拷贝。

在深拷贝中,将创建一个全新的对象,因此,旧对象状态的变化不会反映新创建的实例中的任何更改。

在浅拷贝中,我们创建一个新对象,该对象具有对现有对象的引用。因此,旧对象状态的任何更改都将反映在新创建的实例中。

该图更好地说明了以上两个定义:

深拷贝与浅拷贝

什么是深拷贝

从现有对象创建新对象称为深拷贝。这种类型的拷贝没有对当前对象的任何引用。深拷贝是一项迭代任务。它以递归方式将内部成员变量和对象复制到新实例中。

这种类型的克隆将复制所有嵌套对象,并且在源和副本之间不保留任何引用链接。此克隆精确地复制了所有原始(字节,短型,整型)和非原始(字符串,数组,类)数据类型。

如果要深拷贝对象,请从 Object 类覆盖 Cloneable 接口的 clone() 方法。

这是用 Java 深拷贝 ArrayList 的代码示例:

package deepVsShallowCopy;

public class Car implements Cloneable {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Car(String name) {
        this.name = name;
    }

    @Override
    public Car clone() throws CloneNotSupportedException {
        Car newCar = (Car) super.clone();
        newCar.setName(newCar.getName());
        return newCar;
    }
}

在上面的 POJO 类中,应该重写 clone 方法以及 gettersetter 方法。clone() 方法会抛出 CloneNotSupportedException,我们应该在被覆盖的方法中抛出该异常。

我们应该实现我们的版本以克隆现有对象。我们必须将 Car 类的所有成员变量复制到新实例中。

以下是用于深复制 ArrayList 的驱动程序类实现:

package deepVsShallowCopy;

import java.util.ArrayList;
import java.util.List;

public class DeepCopyArrayList {
    public static void main(String[] args) throws CloneNotSupportedException {
      
        //instantiate car instance 
        Car oldCar = new Car("Ambassador");
        //instantiate an arraylist
        List<Car> oldList = new ArrayList<Car>();
        //add oldCar object into the list
        oldList.add(oldCar);
        
        //instantiate newList
        List<Car> newList = new ArrayList<Car>();
        //add object created using clone() into list
        newList.add(oldList.get(0).clone());
        //rename field in newList car element
        newList.get(0).setName("Rolls Royce");

        System.out.println("oldName : " + oldList.get(0).getName()); //oldName : Ambassador
        System.out.println("newName : " + newList.get(0).getName()); //newName : Rolls Royce
    }
}

在上述实现中,调用了 Car 类的重载 clone() 方法,该方法将返回一个全新的实例。并将这个新创建的实例添加到 ArrayList 中。

当我们在新创建的对象中进行一些操作时,这不会影响旧对象的引用。

另外,如果我们想在 ArrayList 中单独进行迭代,则将在 Car 的对象上调用 clone() 方法,即

for(Car c: oldList){
  newList.add(c.clone());
}
Rashmi Patidar avatar Rashmi Patidar avatar

Rashmi is a professional Software Developer with hands on over varied tech stack. She has been working on Java, Springboot, Microservices, Typescript, MySQL, Graphql and more. She loves to spread knowledge via her writings. She is keen taking up new things and adopt in her career.

LinkedIn

相关文章 - Java ArrayList