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

Xxx*_*xxo 3 java iterator clone arraylist

我的问题是基于这样的假设:该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>();
Run Code Online (Sandbox Code Playgroud)

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

foo2.addAll(foo1.clone());
Run Code Online (Sandbox Code Playgroud)

因为:

foo2.addAll(foo1);
Run Code Online (Sandbox Code Playgroud)

会导致(?)foo1并在其中foo2包含相同的BooClass对象.

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

Iterator<BooClass> itBoo = foo1.iterator();
while(itBoo.hasNext()) foo2.add(itBoo.next().clone());
Run Code Online (Sandbox Code Playgroud)

要么:

foo2.addAll(foo1.clone());
Run Code Online (Sandbox Code Playgroud)

JB *_*zet 6

这两个人不做同样的事情.

Iterator<BooClass> itBoo = foo1.iterator();
while(itBoo.hasNext()) foo2.add(itBoo.next().clone());
Run Code Online (Sandbox Code Playgroud)

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

foo2.addAll(foo1.clone());
Run Code Online (Sandbox Code Playgroud)

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

foo2.addAll(foo1);
Run Code Online (Sandbox Code Playgroud)

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

List<BooClass> foo2 = new ArrayList<>(foo1.size());
for (BooClass boo : foo1) {
    foo2.add(boo.clone());
}
Run Code Online (Sandbox Code Playgroud)

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

List<BooClass> foo2 = new ArrayList<>(foo1.size());
for (BooClass boo : foo1) {
    foo2.add(new BooClass(boo));
}
Run Code Online (Sandbox Code Playgroud)

  • 你什么意思?您无法更改ArrayList.clone()的实现.所以你强制要明确地创建列表中每个元素的克隆.最好的方法是避免使用破坏和设计糟糕的clone(),并使用复制构造函数. (2认同)