我如何克隆一个数组列表,也克隆其项目在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中的对象不一样。
当前回答
一种糟糕的方法是用反思来做这件事。这种方法对我很管用。
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<>();
}
}
其他回答
您需要手动克隆数组列表(通过迭代数组列表并将每个元素复制到一个新的数组列表中),因为clone()不会为您做这件事。原因是ArrayList中包含的对象本身可能无法实现Clonable。
编辑:…而这正是Varkhan的代码所做的。
对于你的对象重写clone()方法
class You_class {
int a;
@Override
public You_class clone() {
You_class you_class = new You_class();
you_class.a = this.a;
return you_class;
}
}
调用.clone() for Vector obj或ArraiList obj....
我认为目前的绿色答案很糟糕,为什么你会问?
它可能需要添加大量代码 它要求你列出所有要复制的列表并这样做
序列化的方式在我看来也是不好的,你可能不得不到处添加Serializable。
那么解决方案是什么呢?
Java深度克隆库 克隆库是一个小型的开源(apache许可)java库,它对对象进行深度克隆。对象不必实现克隆接口。实际上,这个库可以克隆任何java对象。它可以用在缓存实现中,如果你不想修改缓存对象,或者当你想创建对象的深度副本时。
Cloner cloner=new Cloner();
XX clone = cloner.deepClone(someObjectOfTypeXX);
请登录https://github.com/kostaskougios/cloning查看
所有标准集合都有复制构造函数。使用它们。
List<Double> original = // some list
List<Double> copy = new ArrayList<Double>(original); //This does a shallow copy
Clone()的设计有几个错误(请参阅这个问题),所以最好避免使用它。
来自Effective Java第二版,第11项:明智地覆盖克隆
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.
这本书还描述了复制构造函数相对于克隆/克隆的许多优点。
他们不依赖于有风险的语言外对象创造 机制 他们不要求严格遵守文件记录不全的约定 它们与final字段的正确使用并不冲突 它们不会抛出不必要的受控异常 它们不需要类型转换。
考虑使用复制构造函数的另一个好处:假设您有一个HashSet,并且希望将其复制为TreeSet。克隆方法不能提供这种功能,但是使用转换构造函数new TreeSet(s)就很容易实现。
我一直使用这个选项:
ArrayList<Dog> clonedList = new ArrayList<Dog>(name_of_arraylist_that_you_need_to_Clone);