我有一个ArrayList<Widget>
我希望“深入”克隆,以便对原始列表中的任何项目进行修改对克隆列表中的项目没有任何影响:
ArrayList<Widget> origList = getMyList();
ArrayList<Widget> cloneList = origList.clone();
// Remove the 5th Widget from the origina list
origList.remove(4);
// However, the cloneList still has the 5th Widget and is unchanged
// Change the id of the first widget
origList.get(0).setId(20);
// However in cloneList, the 1st Widget's ID is not 20
实现这一目标的最佳/最安全的方法是什么?我想它并不像以下那么简单:
ArrayList<Widget> cloneList = origList.clone();
我想象这是一个内置的ArrayList
类型,加上它的泛型这一事实会使事情变得复杂。我还想象我需要为clone()
类写一个特殊的Widget
覆盖?
提前致谢!
修改:
如果有一个公共JAR在那里为我做这个繁重的工作,我也会完全接受,所以请随意提出建议,但我仍然想知道如何做这个时尚方式所以我可以学习; - )
答案 0 :(得分:5)
这是一项非常重要的任务,我建议您使用其中一个可用的库,例如http://code.google.com/p/cloning/
另请参阅:Java: recommended solution for deep cloning/copying an instance
如果你想看看它是如何完成的,那么获取一个开源库并查看源代码:)
答案 1 :(得分:4)
您需要遍历原始列表中的每个项目并单独克隆每个项目,然后将它们添加到“克隆”项目的新列表中。
类似的东西:
List<Widget> origList = getMyList();
List<Widget> clonedList = clone(origList);
private List<Widget> clone(List<Widget> listToClone) {
List<Widget> clonedList = new LinkedList<Widget>();
for (Widget widget : listToClone) {
clonedList.add(widget.clone());
}
return clonedList;
}
要实现此目的,您必须让Widget
对象实现Cloneable
接口和clone()
方法。不需要任何其他东西。
但是,正如其他海报所说的那样,许多人会争辩说Java中的clone
实现并不值得依赖,最好避免使用。
答案 2 :(得分:2)
有些当局不鼓励使用clone
。 Here is one link off google。这并不是说不要做,而只是要知道你正在做什么,并确保测试(好吧,总是这样做)。
我可能会在根类上放置deepCopy
方法,然后使用复制构造函数复制强制方式。复制构造函数是一个构造函数,它接受有问题的类的实例,并创建一个新实例,将参数的内部状态复制到新实例中。
答案 3 :(得分:1)
您可能需要查看此内容:http://code.google.com/p/cloning/