Deep Copy ArrayList en Java

Rashmi Patidar 15 febrero 2024
Deep Copy ArrayList en Java

En el lenguaje Java, si queremos copiar una ArrayList, puede haber dos formas de hacerlo. Haga una copia profunda o una copia superficial.

En la copia profunda, se crea un objeto completamente nuevo y, por lo tanto, la variación en el estado del objeto antiguo no reflejará ningún cambio en la instancia recién creada.

En la copia superficial, creamos un nuevo objeto que tiene referencias al objeto existente. Entonces, cualquier cambio en el estado del objeto antiguo se reflejará en la instancia recién creada.

El diagrama que ilustra mejor las dos definiciones anteriores:

Copia profunda vs superficial

¿Qué es Deep Copy?

La creación de un nuevo objeto a partir de uno existente se denomina copia profunda. Este tipo de copia no tiene ninguna referencia al presente objeto. Una copia profunda es una tarea iterativa. Copia de forma recursiva los objetos y las variables miembro internas en la nueva instancia.

Este tipo de clon copia todos los objetos anidados y no deja ningún vínculo de referencia entre la fuente y la copia. Esta clonación copia exactamente todos los tipos de datos primitivos (byte, short, int) y no primitivos (String, Array, Class).

Si queremos hacer una copia profunda de un objeto, anule el método clone() de la interfaz Cloneable de la clase Object.

Aquí está el ejemplo de código de una copia profunda de ArrayList en Java:

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;
  }
}

En la clase POJO anterior, se debe anular el método clon, junto con getters y setters. El método clone arroja CloneNotSupportedException que deberíamos incluir en el método anulado.

Deberíamos implementar nuestra versión para hacer un clon del objeto existente. Tenemos que copiar todas las variables miembro de la clase Car en una nueva instancia.

A continuación se muestra la implementación de la clase de controlador para una copia profunda de 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
  }
}

En la implementación anterior, se llama al método clone() anulado de la clase Car, que devolverá una instancia completamente nueva. Y esta instancia recién creada se agregará a ArrayList.

Y cuando hacemos algunas manipulaciones en el objeto recién creado, esto no afectará la referencia del objeto anterior.

Además, si queremos iterar en un ArrayList individualmente, el método clone() debe llamarse sobre el objeto de Car.

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

Artículo relacionado - Java ArrayList