如何克隆ArrayList和复制其内容?

如何克隆ArrayList和复制其内容?

我如何克隆ArrayList也用Java克隆它的项目?

例如,我有:

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

我希望在clonedList和狗的名单不一样。


斯蒂芬大帝
浏览 2313回答 4
4回答

噜噜哒

您将需要对项目进行迭代,并逐一克隆它们,并在执行过程中将克隆放入结果数组中。public&nbsp;static&nbsp;List<Dog>&nbsp;cloneList(List<Dog>&nbsp;list)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;List<Dog>&nbsp;clone&nbsp;=&nbsp;new&nbsp;ArrayList<Dog>(list.size()); &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(Dog&nbsp;item&nbsp;:&nbsp;list)&nbsp;clone.add(item.clone()); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;clone;}很明显,要想让它起作用,你必须得到你的Dog类实现Cloneable接口并覆盖clone()方法。

互换的青春

就我个人而言,我想在Dog中添加一个构造函数:class&nbsp;Dog{ &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Dog() &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;...&nbsp;}&nbsp;//&nbsp;Regular&nbsp;constructor &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Dog(Dog&nbsp;dog)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Copy&nbsp;all&nbsp;the&nbsp;fields&nbsp;of&nbsp;Dog. &nbsp;&nbsp;&nbsp;&nbsp;}}然后只需迭代(如Varkhan的答案所示):public&nbsp;static&nbsp;List<Dog>&nbsp;cloneList(List<Dog>&nbsp;dogList)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;List<Dog>&nbsp;clonedList&nbsp;=&nbsp;new&nbsp;ArrayList<Dog>(dogList.size()); &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(Dog&nbsp;dog&nbsp;:&nbsp;dogList)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clonedList.add(new&nbsp;Dog(dog)); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;clonedList;}我发现这样做的好处是,您不需要在Java中乱搞破克隆的东西。它还与复制Java集合的方式相匹配。另一种选择是编写自己的ICloneable接口并使用它。这样,您就可以编写一个用于克隆的通用方法。

青春有我

所有标准集合都有副本构造函数。用它们。List<Double>&nbsp;original&nbsp;=&nbsp;//&nbsp;some&nbsp;listList<Double>&nbsp;copy&nbsp;=&nbsp;new&nbsp;ArrayList<Double>(original);&nbsp;//This&nbsp;does&nbsp;a&nbsp;shallow&nbsp;copyclone()设计时有几个错误(请参阅这个问题),所以最好避免它。从…有效Java第二版,项目11:明智地覆盖克隆考虑到与cloneable相关的所有问题,可以肯定地说,其他接口不应该扩展它,为继承而设计的类(项目17)不应该实现它。由于它的许多缺点,一些专业的程序员只是选择永远不覆盖克隆方法,从来不调用它,也许,除了复制数组。如果为继承设计类,请注意,如果选择不提供行为良好的受保护的克隆方法,子类不可能实现cloneable。本书还描述了复制构造器相对于克隆/克隆具有的许多优点。他们不依赖于一种易受风险的语言外对象创建机制。它们并不要求对文件很少的公约进行强制执行。它们与最终字段的正确使用没有冲突它们不会抛出不必要的检查异常他们不需要石膏。考虑使用复制构造函数的另一个好处:假设您有一个HashSet s,而您希望将其复制为TreeSet..克隆方法不能提供此功能,但使用转换构造函数很容易:new TreeSet(s).

慕森王

Java 8提供了一种新的方法来调用元素狗上的复制构造函数或克隆方法:溪流,&nbsp;兰巴斯和收藏家.复制构造函数:List<Dog>&nbsp;clonedDogs&nbsp;=&nbsp;dogs.stream().map(Dog::new).collect(toList());表达Dog::new称为a方法参考..它创建一个函数对象,该对象调用Dog以另一只狗为论据。克隆方法[1]:List<Dog>&nbsp;clonedDogs&nbsp;=&nbsp;dogs.stream().map(d&nbsp;->&nbsp;d.clone()).collect(toList());得到一个ArrayList结果或者,如果你必须得到一个ArrayListBack(万一您以后想修改它):ArrayList<Dog>&nbsp;clonedDogs&nbsp;=&nbsp;dogs.stream().map(Dog::new).collect(toCollection(ArrayList::new));更新列表如果不需要保留dogs列表,您可以使用replaceAll方法并更新列表:dogs.replaceAll(Dog::new);所有的例子都假设import static java.util.stream.Collectors.*;.收集器ArrayLists上一个示例中的收集器可以变成util方法。既然这是一件很平常的事,我个人喜欢它又短又漂亮。就像这样:ArrayList<Dog>&nbsp;clonedDogs&nbsp;=&nbsp;dogs.stream().map(d&nbsp;->&nbsp;d.clone()).collect(toArrayList());public&nbsp;static&nbsp;<T> &nbsp;Collector<T,&nbsp;?,&nbsp;ArrayList<T>>&nbsp;toArrayList()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Collectors.toCollection(ArrayList::new);}[1]关于CloneNotSupportedException:若要使此解决方案运行在clone方法Dog&nbsp;绝不能宣布它抛出CloneNotSupportedException..原因是map不允许抛出任何已检查的异常。就像这样:&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Note:&nbsp;Method&nbsp;is&nbsp;public&nbsp;and&nbsp;returns&nbsp;Dog,&nbsp;not&nbsp;Object &nbsp;&nbsp;&nbsp;&nbsp;@Override &nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Dog&nbsp;clone()&nbsp;/*&nbsp;Note:&nbsp;No&nbsp;throws&nbsp;clause&nbsp;here&nbsp;*/&nbsp;{&nbsp;...不过,这不应该是个大问题,因为这是最好的做法。(效果Java例如,给出这个建议。)感谢古斯塔沃注意到这一点。PS:如果您发现它更漂亮,您可以使用方法引用语法来做完全相同的事情:List<Dog>&nbsp;clonedDogs&nbsp;=&nbsp;dogs.stream().map(Dog::clone).collect(toList());
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java