如何复制一个类型为List的ArrayList对象?

7

我了解到Java通过值传递对象引用,如果要创建一个对象的本地副本,可以使用clone()或复制构造函数。我还研究了深拷贝/浅拷贝以及Stack Overflow上的几篇文章。

我正在看这个例子:

List<String> list = new ArrayList<String>();
String one = "one"
list.add(one);

我读过的文章中只有少数提到ArrayList实现了cloneable,但并没有说明如何在类型为List而不是实现了cloneable的ArrayList的情况下制作“list”的本地副本。

如果“list”是ArrayList类型,我可以调用clone()方法。

ArrayList<String> list = new ArrayList<String>();
list.clone();

但如果类型是List,我就无法这样做。

我应该像下面这样使用复制构造函数来制作本地副本吗?制作“list”的副本的最佳方法是什么?

List<String> tmpList = new ArrayList<String>(list);
3个回答

5
将列表传递到构造函数中可能是最好的方式。构造函数本身将在后台使用System.arraycopy。因此,它将有效地将本地副本与通过构造函数传递的列表分离。

0

尽可能使用复制构造函数。 clone() 已经过时,不应在新代码中使用(也不应实现)。

如果您扩展了一个实现了 Cloneable 的类,则除了实现良好的 clone 方法外,别无选择。否则,最好提供替代的对象复制方式,或者干脆不提供该功能。 [...] 一种很好的对象复制方法是提供一个复制构造函数复制工厂 [...]

考虑到与 Cloneable 相关的所有问题,可以放心地说,其他接口不应扩展它,为继承而设计的类(第17条)也不应实现它。由于其许多缺点,一些专家程序员选择永远不覆盖 clone 方法,并且从不调用它,除非是为了复制数组。

来自Effective Java第二版,第11条。


我不明白。 "与可克隆相关的问题"究竟是什么,为什么它们如此严重,以至于你甚至不能调用它? - Russell Silva
1
@RussellSilva,http://jtechies.blogspot.hu/2012/07/item-11-override-clone-judiciously.html - Péter Török

0

从您的问题来看,似乎您想要使您的集合不可修改,这样您就可以使用Collections.unmodifiableList()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接