【问题标题】:Iterators VS ArrayList.addAll() with clone method in JAVAJAVA中带有克隆方法的迭代器VS ArrayList.addAll()
【发布时间】: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); 的结果相同

标签: java arraylist iterator clone


【解决方案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)
猜你喜欢
  • 1970-01-01
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 2012-09-14
  • 2012-12-18
  • 2018-03-07
相关资源
最近更新 更多