JAVA中带有克隆方法的迭代器VS ArrayList.addAll()

Posted

技术标签:

【中文标题】JAVA中带有克隆方法的迭代器VS ArrayList.addAll()【英文标题】:Iterators VS ArrayList.addAll() with clone method in JAVA 【发布时间】:2015-11-23 23:47:22 【问题描述】:

我的问题是基于ArrayList.addAll() 方法不会生成新对象而是将相同的对象附加到 ArrayList 的假设。

因此,为了addAll 对象但也有新对象,则必须进行构造。

例如,假设 BooClass 类实现了具有深拷贝的Cloneable 接口,我们有:

ArrayList<BooClass> foo1 = new ArrayList<BooClass>();
for (int i = 0; i < 10; i++) foo1.add(new BooClass());

ArrayList<BooClass> foo2 = new ArrayList<BooClass>();

然后,如果有人想将foo1 的所有元素添加到foo2 作为new 对象,他应该这样做:

foo2.addAll(foo1.clone());

因为:

foo2.addAll(foo1);

将导致 (?) foo1foo2 在其中具有相同的 BooClass 对象。

所以,如果以上是正确的,那么我的问题是两者哪个更快:

Iterator<BooClass> itBoo = foo1.iterator();
while(itBoo.hasNext()) foo2.add(itBoo.next().clone());

或:

foo2.addAll(foo1.clone());

?

【问题讨论】:

1.没关系。 2.如果真的很重要,你可以自己测试一下。 3. 除非您说的是数百万份/克隆,否则没关系。 那么,两者对于流程的复杂度“程度”是一样的吗? 是的,他们都是O(n)。迭代器方法不太清楚。 实际上它们并不相同(嗯,在复杂性方面是的,但不是功能)。 ArrayList.clone(); 不会产生深度克隆。所以相当于一个简单的addAll() ArrayList.clone 返回浅拷贝。 foo2.addAll(foo1.clone())foo2.addAll(foo1); 的结果相同 【参考方案1】:

两者不做同样的事情。

Iterator<BooClass> itBoo = foo1.iterator();
while(itBoo.hasNext()) foo2.add(itBoo.next().clone());

这会克隆foo1 中的每个BooClass 对象,并将克隆添加到foo2

foo2.addAll(foo1.clone());

克隆 列表 foo1,生成一个新的 ArrayList,其中包含对 foo1 相同的 BooClass 对象的引用,并将所有这些 BooClass 对象添加到 foo2。 顺便说一句,克隆操作完全没用,因为这与简单的操作具有相同的效果

foo2.addAll(foo1);

如果你想要一个深度克隆,最简单的方法是

List<BooClass> foo2 = new ArrayList<>(foo1.size());
for (BooClass boo : foo1) 
    foo2.add(boo.clone());

请注意,clone() 通常被认为是一个坏主意。您通常应该更喜欢复制构造函数:

List<BooClass> foo2 = new ArrayList<>(foo1.size());
for (BooClass boo : foo1) 
    foo2.add(new BooClass(boo));

【讨论】:

foo1 上的clone() 不会导致调用ArrayList 中的对象的clone()?如果是这种情况,那么通过调用addAll(),您只需将foo1same 对象添加到foo2? @Kostas 你明白了。 clone() 不是递归的。这是documented:返回此 ArrayList 实例的浅表副本。 (元素本身不会被复制。) 那么,在clone 方法中实际执行复制构造功能是否被认为是一种好习惯? 什么意思?您不能更改 ArrayList.clone() 的实现。因此,您必须明确创建列表中每个元素的克隆。最好的方法是避免使用损坏且设计不良的 clone() ,而是使用复制构造函数。 最好的做法是忘记 clone() 并提供一个复制构造函数:public BooClass(BooClass oldObject)

以上是关于JAVA中带有克隆方法的迭代器VS ArrayList.addAll()的主要内容,如果未能解决你的问题,请参考以下文章

python中带有迭代器的while循环,它不断变化

迭代器VS生成器

克隆() vs 复制构造函数 vs 工厂方法?

复习迭代器 VS 生成器

事件 vs 流 vs Observables vs 异步迭代器

如何克隆文件名中带有冒号的文件