Copia profonda ArrayList in Java

Rashmi Patidar 15 febbraio 2024
Copia profonda ArrayList in Java

In linguaggio Java, se vogliamo copiare un ArrayList, ci possono essere due modi per farlo. O fai una copia profonda o una copia superficiale.

Nella copia profonda, viene creato un oggetto completamente nuovo e quindi la variazione nello stato del vecchio oggetto non rifletterà alcun cambiamento nell’istanza appena creata.

Nella copia superficiale, creiamo un nuovo oggetto che ha riferimenti all’oggetto esistente. Quindi qualsiasi cambiamento nello stato del vecchio oggetto si rifletterà nell’istanza appena creata.

Il diagramma che illustra meglio le due definizioni precedenti:

Copia profonda o superficiale

Cos’è Deep Copy

La creazione di un nuovo oggetto da uno esistente è chiamata copia profonda. Questo tipo di copia non ha alcun riferimento all’oggetto presente. Una copia profonda è un’attività iterativa. Copia ricorsivamente le variabili membro interne e gli oggetti nella nuova istanza.

Questo tipo di clone copia tutti gli oggetti nidificati e non lascia alcun collegamento di riferimento tra l’origine e la copia. Questa clonazione copia esattamente tutti i tipi di dati primitivi (byte, short, int) e non primitivi (String, Array, Class).

Se vogliamo copiare in profondità un oggetto, sovrascrivere il metodo clone() dell’interfaccia Cloneable dalla classe Object.

Ecco il codice di esempio della copia completa di un ArrayList in 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;
  }
}

Nella precedente classe POJO, si dovrebbe sovrascrivere il metodo clone, insieme a getter e setters. Il metodo clone() genera CloneNotSupportedException che dovremmo lanciare nel metodo sovrascritto.

Dovremmo implementare la nostra versione per creare un clone dell’oggetto esistente. Dobbiamo copiare tutte le variabili membro della classe Car in una nuova istanza.

Di seguito è riportata l’implementazione della classe driver per la copia completa di un 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
  }
}

Nell’implementazione precedente, viene chiamato il metodo clone() sovrascritto della classe Car, che restituirà un’istanza completamente nuova. E questa istanza appena creata deve essere aggiunta a ArrayList.

E quando effettuiamo alcune manipolazioni nell’oggetto appena creato, ciò non influirà sul vecchio riferimento all’oggetto.

Inoltre, se vogliamo iterare in un ArrayList individualmente, il metodo clone() deve essere chiamato sull’oggetto di 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

Articolo correlato - Java ArrayList