How can I clone an ArrayList
and also clone its items in Java?
For example I have:
ArrayList dogs = getDogs();
ArrayList
You will need to clone the ArrayList
by hand (by iterating over it and copying each element to a new ArrayList
), because clone()
will not do it for you. Reason for this is that the objects contained in the ArrayList
may not implement Clonable
themselves.
Edit: ... and that is exactly what Varkhan's code does.
The below worked for me..
in Dog.java
public Class Dog{
private String a,b;
public Dog(){} //no args constructor
public Dog(Dog d){ // copy constructor
this.a=d.a;
this.b=d.b;
}
}
-------------------------
private List<Dog> createCopy(List<Dog> dogs) {
List<Dog> newDogsList= new ArrayList<>();
if (CollectionUtils.isNotEmpty(dogs)) {
dogs.stream().forEach(dog-> newDogsList.add((Dog) SerializationUtils.clone(dog)));
}
return newDogsList;
}
Here the new list which got created from createCopy method is created through SerializationUtils.clone(). So any change made to new list will not affect original list
The other posters are correct: you need to iterate the list and copy into a new list.
However... If the objects in the list are immutable - you don't need to clone them. If your object has a complex object graph - they will need to be immutable as well.
The other benefit of immutability is that they are threadsafe as well.
Easy way by using commons-lang-2.3.jar that library of java to clone list
link download commons-lang-2.3.jar
How to use
oldList.........
List<YourObject> newList = new ArrayList<YourObject>();
foreach(YourObject obj : oldList){
newList.add((YourObject)SerializationUtils.clone(obj));
}
I hope this one can helpful.
:D
A nasty way is to do it with reflection. Something like this worked for me.
public static <T extends Cloneable> List<T> deepCloneList(List<T> original) {
if (original == null || original.size() < 1) {
return new ArrayList<>();
}
try {
int originalSize = original.size();
Method cloneMethod = original.get(0).getClass().getDeclaredMethod("clone");
List<T> clonedList = new ArrayList<>();
// noinspection ForLoopReplaceableByForEach
for (int i = 0; i < originalSize; i++) {
// noinspection unchecked
clonedList.add((T) cloneMethod.invoke(original.get(i)));
}
return clonedList;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
System.err.println("Couldn't clone list due to " + e.getMessage());
return new ArrayList<>();
}
}
Simple way is
ArrayList<Dog> dogs = getDogs();
ArrayList<Dog> clonedList = new ArrayList<Dog>(dogs);