当迭代LinkedList时,get(i)是O(N)操作。然后我们使用Iterator对象遍历列表是有道理的。但是使用ArrayList,get(i)是O(1)。那么,在这种情况下我是否正确地说,当使用ArrayList时,无论我们使用c风格的循环还是Iterator对象,它都没有区别?
答案 0 :(得分:2)
你是对的。你应该避免像这样的循环
for (int i = 0; i < linkedList.size(); i++) {
... linkedList.get(i) ...
}
代表LinkedList
因为get(i)
为O(n)
所以整个过程变为O(n^2)
。
对于ArrayList
,iterator.next()
和get(i)
O(1)
都无关紧要。
但是,即使对于Iterator
,您通常也不需要明确使用LinkedList
对象,因为foreach循环for (Object object : linkedList)
无论如何都会在后台使用Iterator
。< / p>
Iterator
只需要在相对罕见的情况下明确使用(例如,过滤List
或并行遍历两个LinkedList
。
答案 1 :(得分:0)
是的,O(n)
两种情况都是ArrayList
。如果您正在使用迭代器来查找元素,那么在最坏的情况下,您必须检查每个元素。在一般情况下,你必须检查一半。因此它仍然是O(n)
。
此外,迭代列表的for
语法只是用于调用迭代器的语法糖。如果查看编译的字节码,您将看到它调用列表的迭代器。
例如,以下代码:
import java.util.*;
public class IterTest {
public static void main() {
List<String> l = new ArrayList<>();
for(String s : l) {
System.out.println(s);
}
}
}
具有以下字节码:
Compiled from "IterTest.java"
public class IterTest {
public IterTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main();
Code:
0: new #2 // class java/util/ArrayList
3: dup
4: invokespecial #3 // Method java/util/ArrayList."<init>":()V
7: astore_0
8: aload_0
9: invokeinterface #4, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
14: astore_1
15: aload_1
16: invokeinterface #5, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
21: ifeq 44
24: aload_1
25: invokeinterface #6, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
30: checkcast #7 // class java/lang/String
33: astore_2
34: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
37: aload_2
38: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
41: goto 15
44: return
你可以看到它使用迭代器遍历列表。
<强>更新强>
回应你的评论:
如果使用for
,带有索引的for
循环将具有与显式迭代器和ArrayList
迭代器样式循环相同的性能。
但是,使用带有for
索引的LinkedList
将严格(平均)比ArrayList
更严重,因为对于每个索引,您正在执行 O(n)查找。因此,您的总体表现实际上最终是 O(n 2 )。
答案 2 :(得分:0)
与while循环相比,使用Iterator
在删除元素时更不容易出错,因为在删除时你不必调整某个位置值(i,光标,无论你怎么称呼它) 。正如@Vivin Paliath解释的那样,for循环已经在使用迭代器了,并且不能使用删除(删除会导致ConcurrentModificationException
)。