ArrayList clone() – Deep copy and shallow copy

ArrayList clone() method is used to create a shallow copy of the list. In the new list, only object references are copied.

If we change the object state inside the first ArrayList, then the changed object state will be reflected in the cloned ArrayList as well.

1. ArrayList clone() API

clone() method create a new ArrayList and then copies the backing array to cloned array.

public Object clone() {
    try {
        ArrayList<?> v = (ArrayList<?>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError(e);
    }
}
  • Method parameter – none.
  • Method returns – cloned arraylist.
  • Method throws – no exception.

2. Creating Shallow Copy

Java program to create a shallow copy of an arraylist using clone() method.

import java.util.ArrayList;

public class ArrayListExample 
{
    @SuppressWarnings("unchecked")
    public static void main(String[] args) 
    {
        ArrayList<String> arrayListObject = new ArrayList<>(); 
        
        arrayListObject.add("A");
        arrayListObject.add("B");
        arrayListObject.add("C");
        arrayListObject.add("D");
        
        System.out.println(arrayListObject);   
        
        ArrayList<String> arrayListClone =  (ArrayList<String>) arrayListObject.clone();
        
        System.out.println(arrayListClone);   
    }
}

Program output.

[A, B, C, D]
[A, B, C, D]

3. Creating Deep Copy

Creating a deep copy of a list is not straightforward. Java does not support deep copying by default. So we have to manually modify the code to enable the deep copying of classes and collections.

Read More : A guide to object cloning in Java

3.1. Deep copy of Java class

In Java, to support deep copy, we must override the clone() of model classes. In clone() method, we must ensure that when somebody invokes object.clone() method then it must return a deep copy of that model class (e.g. Employee class).

To create a deep copy of the class, divide all the class members into two categories of mutable and immutable types.

  1. All immutable field members can be used as it is. They don’t require any special treatment. e.g. primitive classes, wrapper classes and String class.
  2. For all immutable field members, we must create a new object of member and assign it’s value to cloned object.

The idea is to return an immutable copy of the class from clone() method.

package com.howtodoinjava.example;

import java.util.Date;

public class Employee implements Cloneable {

    private Long id;
    private String name;
    private Date dob;		//Mutable field

    public Employee(Long id, String name, Date dob) {
        super();
        this.id = id;
        this.name = name;
        this.dob = dob;
    }

    //Getters and setters

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Employee clone = null;
        try 
        {
            clone = (Employee) super.clone();

            //Copy new date object to cloned method
            clone.setDob((Date) this.getDob().clone());
        } 
        catch (CloneNotSupportedException e) 
        {
            throw new RuntimeException(e);
        }
        return clone;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", dob=" + dob + "]";
    }
}

3.2. Deep copy of Java Collections

Creating a deep copy of a collection is rather easy. We need to create a new instance of collection and copy all elements from given collection to cloned collection – one by one. Note that we will copy the element’s clone in cloned collection.

ArrayList<Employee> employeeList = new ArrayList<>(); 
ArrayList<Employee> employeeListClone = new ArrayList<>();

Iterator<Employee> iterator = employeeList.iterator();

while(iterator.hasNext())
{
	//Add the object clones
    employeeListClone.add((Employee) iterator.next().clone());	
}

3.3. ArrayList deep copy example

Java program to create a deep copy of an arraylist.

package com.howtodoinjava.example;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

public class ArrayListExample 
{
    @SuppressWarnings("deprecation")
    public static void main(String[] args) throws CloneNotSupportedException 
    {
        ArrayList<Employee> employeeList = new ArrayList<>(); 
        
        employeeList.add(new Employee(1l, "adam", new Date(1982, 02, 12)));
        
        System.out.println(employeeList);   
        
        ArrayList<Employee> employeeListClone = new ArrayList<>(); 
        
        Iterator<Employee> iterator = employeeList.iterator();
        while(iterator.hasNext()){
            employeeListClone.add((Employee) iterator.next().clone());
        }
        
        employeeListClone.get(0).setId(2l);
        employeeListClone.get(0).setName("brian");
        employeeListClone.get(0).getDob().setDate(13);;
        
        System.out.println(employeeList); 
        System.out.println(employeeListClone);   
    }
}

Program output. Notice that even after changing the values of Employee object in employeeListClone, original employee list employeeList is not changed.

[Employee [id=1, name=adam, dob=Sun Mar 12 00:00:00 IST 3882]]

[Employee [id=1, name=adam, dob=Sun Mar 12 00:00:00 IST 3882]]

[Employee [id=2, name=brian, dob=Mon Mar 13 00:00:00 IST 3882]]

Happy Learning !!

Read More:

A Guide to Java ArrayList
ArrayList Java Docs

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

2 thoughts on “ArrayList clone() – Deep copy and shallow copy”

  1. I should say in the following line, you not need to have .clone() at the end.

    while(iterator.hasNext()){
    employeeListClone.add((Employee) iterator.next().clone());
    }

    Reply
  2. Hi Lokesh,

    Running the Employee class in section 3.1 for deep clone, the section in which you are making a clone of dob (this.dob.clone()) will the clone method be visible .

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.