我如何克隆一个数组列表,也克隆其项目在Java?

例如,我有:

ArrayList<Dog> dogs = getDogs();
ArrayList<Dog> clonedList = ....something to do with dogs....

我希望clonedList中的对象与dogs list中的对象不一样。


当前回答

我刚刚开发了一个库,能够克隆一个实体对象和java.util.List对象。只需从https://drive.google.com/open?id=0B69Sui5ah93EUTloSktFUkctN0U下载jar,并使用静态方法cloneListObject(List List)。该方法不仅克隆List,而且克隆所有实体元素。

其他回答

我个人会给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接口并使用它。这样就可以为克隆编写一个泛型方法。

我认为目前的绿色答案很糟糕,为什么你会问?

它可能需要添加大量代码 它要求你列出所有要复制的列表并这样做

序列化的方式在我看来也是不好的,你可能不得不到处添加Serializable。

那么解决方案是什么呢?

Java深度克隆库 克隆库是一个小型的开源(apache许可)java库,它对对象进行深度克隆。对象不必实现克隆接口。实际上,这个库可以克隆任何java对象。它可以用在缓存实现中,如果你不想修改缓存对象,或者当你想创建对象的深度副本时。

Cloner cloner=new Cloner();
XX clone = cloner.deepClone(someObjectOfTypeXX);

请登录https://github.com/kostaskougios/cloning查看

List<Dog> dogs;
List<Dog> copiedDogs = dogs.stream().map(dog -> SerializationUtils.clone(dog)).Collectors.toList());

这将深度复制每个狗

我刚刚开发了一个库,能够克隆一个实体对象和java.util.List对象。只需从https://drive.google.com/open?id=0B69Sui5ah93EUTloSktFUkctN0U下载jar,并使用静态方法cloneListObject(List List)。该方法不仅克隆List,而且克隆所有实体元素。

一种糟糕的方法是用反思来做这件事。这种方法对我很管用。

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<>();
    }
}