Deep Copy ArrayList in Java

In Java language, if we want to copy an ArrayList, there can be two ways to do that. Either do a deep copy or a shallow copy.

In the deep copy, a completely new object is created, and hence the variation in the old object’s state will not reflect any change in the newly created instance.

In the shallow copy, we create a new object that has references to the existing object. So any change in the old object’s state will reflect in the newly created instance.

The Diagram that better illustrates the above two definitions:

Deep vs shallow copy

What is Deep Copy

The creation of a new object from an existing one is called a deep-copy. This type of copy does not have any references to the present object. A deep-copy is an iterative task. It recursively copies the internal member variables and objects into the new instance.

This type of clone copies all the nested objects and does not leave any reference links between the source and the copy. This cloning copies all the primitive (byte, short, int) and non-primitive (String, Array, Class) datatypes exactly.

If we want to deep-copy an object, override the clone() method of the Cloneable interface from the Object class.

Here is the code sample of deep copy an 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;
    }
}

In the above POJO class, one should override the clone method, along with getters and setters. The clone() method throws CloneNotSupportedException that we should throw in the overridden method.

We should implement our version to make a clone of the existing object. We have to copy all the member variables of the Car class into a new instance.

Below is the driver class implementation for deep copy an 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
    }
}

In the above implementation, the overridden clone() method of Car class is called, which will return a completely new instance. And this newly created instance is to been added to the ArrayList.

And when we make some manipulations in the newly created object, this will not affect the old object reference.

Also, if we want to iterate in an ArrayList individually clone() method is to be called over Car’s object i.e.

for(Car c: oldList){
  newList.add(c.clone());
}
Contribute
DelftStack is a collective effort contributed by software geeks like you. If you like the article and would like to contribute to DelftStack by writing paid articles, you can check the write for us page.

Related Article - Java ArrayList

  • Copy ArrayList in Java
  • Convert Int Array to Arraylist in Java