如果您只是在集合上徘徊以读取所有值,那么使用迭代器或新的for循环语法之间没有区别,因为新语法只是在水下使用迭代器。
但是,如果您的意思是循环旧的“c-style”循环:
for(int i=0; i<list.size(); i++) {
Object o = list.get(i);
}
然后,新的 for 循环或迭代器可以更加高效,具体取决于底层数据结构。这样做的原因是,对于某些数据结构,是O(n)操作,这使得循环成为O(n2)操作。传统的链表就是这种数据结构的一个例子。所有迭代器的基本要求都应该是O(1)操作,使循环成为O(n)。get(i)
next()
要验证新的 for 循环语法是否在水下使用了迭代器,请比较从以下两个 Java 代码段中生成的字节码。首先是 for 循环:
List<Integer> a = new ArrayList<Integer>();
for (Integer integer : a)
{
integer.toString();
}
// Byte code
ALOAD 1
INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
ASTORE 3
GOTO L2
L3
ALOAD 3
INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
CHECKCAST java/lang/Integer
ASTORE 2
ALOAD 2
INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
POP
L2
ALOAD 3
INVOKEINTERFACE java/util/Iterator.hasNext()Z
IFNE L3
第二,迭代器:
List<Integer> a = new ArrayList<Integer>();
for (Iterator iterator = a.iterator(); iterator.hasNext();)
{
Integer integer = (Integer) iterator.next();
integer.toString();
}
// Bytecode:
ALOAD 1
INVOKEINTERFACE java/util/List.iterator()Ljava/util/Iterator;
ASTORE 2
GOTO L7
L8
ALOAD 2
INVOKEINTERFACE java/util/Iterator.next()Ljava/lang/Object;
CHECKCAST java/lang/Integer
ASTORE 3
ALOAD 3
INVOKEVIRTUAL java/lang/Integer.toString()Ljava/lang/String;
POP
L7
ALOAD 2
INVOKEINTERFACE java/util/Iterator.hasNext()Z
IFNE L8
如您所见,生成的字节代码实际上是相同的,因此使用任何一种形式都不会降低性能。因此,对于大多数人来说,您应该选择对您最有吸引力的循环形式,因为该循环的样板代码较少。