Java ArrayList clone example shows how to clone ArrayList in Java. The example also shows how to deep clone ArrayList using the Cloneable interface and copy constructor.
How to clone ArrayList in Java?
Cloning an object comes very handy in certain situations where you need to make a copy of an ArrayList before making any changes to the original ArrayList. You can clone ArrayList using its clone
method.
1 |
Object clone() |
This method returns a shallow copy of the ArrayList.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package com.javacodeexamples.collections.arraylist; import java.util.ArrayList; public class JavaArrayListCloneExample { public static void main(String[] args) { ArrayList<String> aList1 = new ArrayList<String>(); aList1.add("One"); aList1.add("Two"); aList1.add("Three"); //print ArrayList System.out.println("Original ArrayList contents: " + aList1); //clone ArrayList ArrayList<String> aList2 = (ArrayList<String>)aList1.clone(); //print cloned ArrayList System.out.println("Cloned ArrayList contents: " + aList2); /* * Adding/removing original ArrayList * will not affect the cloned ArrayList */ aList1.add("Four"); aList1.remove(0); System.out.println("After add/remove elements in original ArrayList"); //print ArrayList System.out.println("Original ArrayList contents: " + aList1); //print cloned ArrayList System.out.println("Cloned ArrayList contents: " + aList2); } } |
Output
1 2 3 4 5 |
Original ArrayList contents: [One, Two, Three] Cloned ArrayList contents: [One, Two, Three] After add/remove elements in original ArrayList Original ArrayList contents: [Two, Three, Four] Cloned ArrayList contents: [One, Two, Three] |
Please note that, clone
method makes a shallow copy of the ArrayList. That means, the ArrayList object is cloned, but its content is not. ArrayList elements still refer to the same objects. To understand it more clearly, see below given example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com.javacodeexamples.collections.arraylist; import java.util.ArrayList; public class JavaArrayListCloneExample { public static void main(String[] args) { //create StringBuilder object StringBuilder sbText = new StringBuilder("I am object1"); ArrayList<StringBuilder> aList1 = new ArrayList<StringBuilder>(); aList1.add(sbText); //clone the ArrayList ArrayList<StringBuilder> aList2 = (ArrayList<StringBuilder>)aList1.clone(); //change the StringBuilder object sbText.replace(11, 12, "2"); System.out.println("Original ArrayList Contents"); System.out.println(aList1); System.out.println("Cloned ArrayList Contents"); System.out.println(aList2); } } |
Output
1 2 3 4 |
Original ArrayList Contents [I am object2] Cloned ArrayList Contents [I am object2] |
As you can see from the output, when we changed the StringBuilder object, it also affected the contents of the cloned ArrayList. That is because only the ArrayList object was cloned, but its elements were not.
How to deep clone ArrayList and its contents?
As we have seen in the above example, cloning the ArrayList does not clone its elements. The elements still refer to the original objects in the Heap. Changing the element in one List also affects another. To overcome this problem, the ArrayList needs to be deep cloned, which means along with the ArrayList object itself, its elements should also be cloned.
Java provides the Cloneable interface (a marker interface with no methods) to mark that the class implementing it supports cloning.
ArrayList deep cloning example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
package com.javacodeexamples.collections.arraylist; import java.util.ArrayList; public class JavaArrayListCloneExample { public static void main(String[] args){ ArrayList<Student> aListStudents = new ArrayList<Student>(); aListStudents.add(new Student("1", "Ryan")); aListStudents.add(new Student("2", "Julie")); //create the same size ArrayList ArrayList<Student> aListStudentsCopy = new ArrayList<Student>( aListStudents.size() ); try { //iterate over original ArrayList for(Student student : aListStudents){ //clone the element object and add it to ArrayList clone aListStudentsCopy.add( student.clone() ); } } catch (CloneNotSupportedException e) { System.out.println("Cloning is not supported by ArrayList element"); e.printStackTrace(); } System.out.println("Original ArrayList: " + aListStudents); System.out.println("Cloned ArrayList: " + aListStudentsCopy); //change elements in original list aListStudents.get(0).setId("100"); aListStudents.get(1).setId("101"); System.out.println("Original ArrayList: " + aListStudents); System.out.println("Cloned ArrayList: " + aListStudentsCopy); } } class Student implements Cloneable{ private String id; private String name; public Student(){} public Student(String id, String name){ this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString(){ return id + "->" + name; } //override clone method of Object class protected Student clone() throws CloneNotSupportedException{ return (Student)super.clone(); } } |
Output
1 2 3 4 |
Original ArrayList: [1->Ryan, 2->Julie] Cloned ArrayList: [1->Ryan, 2->Julie] Original ArrayList: [100->Ryan, 101->Julie] Cloned ArrayList: [1->Ryan, 2->Julie] |
As you can see from the output, changing the element in the original ArrayList no more affects the cloned ArrayList. Instead of using the clone
method of ArrayList, we iterated through the ArrayList elements and cloned them before adding them to the copied ArrayList. In the Students class, we implemented the Cloneable interface and overridden the clone
method of Object class.
Deep cloning ArrayList using a copy constructor
Instead of implementing the Cloneable interface and overriding the clone
method, we can also write a copy constructor in the Student class. The copy constructor is a constructor that accepts the object of the same class as a parameter and copies all the properties of it as given below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
package com.javacodeexamples.collections.arraylist; import java.util.ArrayList; public class JavaArrayListCloneExample { public static void main(String[] args){ ArrayList<Student> aListStudents = new ArrayList<Student>(); aListStudents.add(new Student("1", "Steve")); aListStudents.add(new Student("2", "Mike")); //create the same size ArrayList ArrayList<Student> aListStudentsCopy = new ArrayList<Student>( aListStudents.size() ); //iterate over original ArrayList for(Student student : aListStudents){ //use copy constructor to copy the Student object aListStudentsCopy.add( new Student(student) ); } System.out.println("Original ArrayList: " + aListStudents); System.out.println("Cloned ArrayList: " + aListStudentsCopy); //change elements in original list aListStudents.get(0).setName("Smith"); aListStudents.get(1).setName("John"); System.out.println("Original ArrayList: " + aListStudents); System.out.println("Cloned ArrayList: " + aListStudentsCopy); } } class Student{ private String id; private String name; public Student(){} public Student(String id, String name){ this.id = id; this.name = name; } //copy constructor public Student(Student student){ this.id = student.id; this.name = student.name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString(){ return id + "->" + name; } } |
Output
1 2 3 4 |
Original ArrayList: [1->Steve, 2->Mike] Cloned ArrayList: [1->Steve, 2->Mike] Original ArrayList: [1->Smith, 2->John] Cloned ArrayList: [1->Steve, 2->Mike] |
This example is a part of the ArrayList in Java Tutorial.
Please let me know your views in the comments section below.