我如何克隆一个数组列表,也克隆其项目在Java?
例如,我有:
ArrayList<Dog> dogs = getDogs();
ArrayList<Dog> clonedList = ....something to do with dogs....
我希望clonedList中的对象与dogs list中的对象不一样。
我如何克隆一个数组列表,也克隆其项目在Java?
例如,我有:
ArrayList<Dog> dogs = getDogs();
ArrayList<Dog> clonedList = ....something to do with dogs....
我希望clonedList中的对象与dogs list中的对象不一样。
当前回答
下面的方法对我有用。
在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;
}
在这里,由createCopy方法创建的新列表是通过SerializationUtils.clone()创建的。 因此,对新列表所做的任何更改都不会影响原始列表
其他回答
其他的海报是正确的:你需要迭代列表并复制到一个新的列表。
然而…… 如果列表中的对象是不可变的-你不需要克隆它们。如果你的对象有一个复杂的对象图,它们也需要是不可变的。
不可变性的另一个好处是它们也是线程安全的。
我个人会给Dog添加一个构造函数:
class Dog
{
public Dog()
{ ... } // Regular constructor
public Dog(Dog dog) {
// Copy all the fields of Dog.
}
}
然后进行迭代(如Varkhan的回答所示):
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;
}
我发现这样做的好处是你不需要在Java中破坏可克隆的东西。它还与复制Java集合的方式相匹配。
另一种选择是编写自己的ICloneable接口并使用它。这样就可以为克隆编写一个泛型方法。
一种糟糕的方法是用反思来做这件事。这种方法对我很管用。
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<>();
}
}
包导入org.apache.commons.lang.SerializationUtils;
有一个方法SerializationUtils.clone(Object);
例子
this.myObjectCloned = SerializationUtils.clone(this.object);
您需要手动克隆数组列表(通过迭代数组列表并将每个元素复制到一个新的数组列表中),因为clone()不会为您做这件事。原因是ArrayList中包含的对象本身可能无法实现Clonable。
编辑:…而这正是Varkhan的代码所做的。