How can I clone an ArrayList
and also clone its items in Java?
For example I have:
ArrayList dogs = getDogs();
ArrayList
I think I found a really easy way to make a deep copy ArrayList. Assuming you want to copy a String ArrayList arrayA.
ArrayList<String>arrayB = new ArrayList<String>();
arrayB.addAll(arrayA);
Let me know if it doesn't work for you.
All standard collections have copy constructors. Use them.
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original); //This does a shallow copy
clone()
was designed with several mistakes (see this question), so it's best to avoid it.
From Effective Java 2nd Edition, Item 11: Override clone judiciously
Given all of the problems associated with Cloneable, it’s safe to say that other interfaces should not extend it, and that classes designed for inheritance (Item 17) should not implement it. Because of its many shortcomings, some expert programmers simply choose never to override the clone method and never to invoke it except, perhaps, to copy arrays. If you design a class for inheritance, be aware that if you choose not to provide a well-behaved protected clone method, it will be impossible for subclasses to implement Cloneable.
This book also describes the many advantages copy constructors have over Cloneable/clone.
Consider another benefit of using copy constructors: Suppose you have a HashSet s
, and you want to copy it as a TreeSet
. The clone method can’t offer this functionality, but it’s easy with a conversion constructor: new TreeSet(s)
.
I have found a way, you can use json to serialize/unserialize the list. The serialized list holds no reference to the original object when unserialized.
Using gson:
List<CategoryModel> originalList = new ArrayList<>(); // add some items later
String listAsJson = gson.toJson(originalList);
List<CategoryModel> newList = new Gson().fromJson(listAsJson, new TypeToken<List<CategoryModel>>() {}.getType());
You can do that using jackson and any other json library too.
The package import org.apache.commons.lang.SerializationUtils;
There is a method SerializationUtils.clone(Object);
Example
this.myObjectCloned = SerializationUtils.clone(this.object);
I, personally, would add a constructor to Dog:
class Dog
{
public Dog()
{ ... } // Regular constructor
public Dog(Dog dog) {
// Copy all the fields of Dog.
}
}
Then just iterate (as shown in Varkhan's answer):
public static List<Dog> cloneList(List<Dog> dogList) {
List<Dog> clonedList = new ArrayList<Dog>(dogList.size());
for (Dog dog : dogList) {
clonedList.add(new Dog(dog));
}
return clonedList;
}
I find the advantage of this is you don't need to screw around with the broken Cloneable stuff in Java. It also matches the way that you copy Java collections.
Another option could be to write your own ICloneable interface and use that. That way you could write a generic method for cloning.
Here is a solution using a generic template type:
public static <T> List<T> copyList(List<T> source) {
List<T> dest = new ArrayList<T>();
for (T item : source) { dest.add(item); }
return dest;
}