哪个更有效,for-each 循环还是迭代器? [英] Which is more efficient, a for-each loop, or an iterator?

查看:30
本文介绍了哪个更有效,for-each 循环还是迭代器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

遍历集合最有效的方法是什么?

Which is the most efficient way to traverse a collection?

List<Integer>  a = new ArrayList<Integer>();
for (Integer integer : a) {
  integer.toString();
}

List<Integer>  a = new ArrayList<Integer>();
for (Iterator iterator = a.iterator(); iterator.hasNext();) {
   Integer integer = (Integer) iterator.next();
   integer.toString();
}

请注意,这不是 thisthisthis,或 this,尽管最后一个问题的答案之一很接近.这不是一个骗局的原因是,其中大多数是比较循环,您在循环内调用 get(i),而不是使用迭代器.

Please note, that this is not an exact duplicate of this, this, this, or this, although one of the answers to the last question comes close. The reason that this is not a dupe, is that most of these are comparing loops where you call get(i) inside the loop, rather than using the iterator.

Meta 上的建议,我将发布我对这个问题的回答.

As suggested on Meta I will be posting my answer to this question.

推荐答案

如果您只是在集合中徘徊以读取所有值,那么使用迭代器或新的 for 循环语法之间没有区别,因为新语法只是在水下使用迭代器.

If you are just wandering over the collection to read all of the values, then there is no difference between using an iterator or the new for loop syntax, as the new syntax just uses the iterator underwater.

但是,如果您的意思是循环旧的c 样式"循环:

If however, you mean by loop the old "c-style" loop:

for(int i=0; i<list.size(); i++) {
   Object o = list.get(i);
}

然后新的 for 循环或迭代器可以更高效,具体取决于底层数据结构.这样做的原因是对于某些数据结构,get(i) 是一个 O(n) 操作,这使得循环成为一个 O(n2) 操作.传统的链表就是这种数据结构的一个例子.所有迭代器都有一个基本要求,next() 应该是一个 O(1) 操作,使循环 O(n).

Then the new for loop, or iterator, can be a lot more efficient, depending on the underlying data structure. The reason for this is that for some data structures, get(i) is an O(n) operation, which makes the loop an O(n2) operation. A traditional linked list is an example of such a data structure. All iterators have as a fundamental requirement that next() should be an O(1) operation, making the loop O(n).

要验证新的 for 循环语法是否在水下使用了迭代器,请比较以下两个 Java 片段中生成的字节码.首先是for循环:

To verify that the iterator is used underwater by the new for loop syntax, compare the generated bytecodes from the following two Java snippets. First the for loop:

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

如您所见,生成的字节码实际上是相同的,因此使用任何一种形式都不会造成性能损失.因此,您应该选择最美观的循环形式,对于大多数人来说,这将是 for-each 循环,因为它的样板代码较少.

As you can see, the generated byte code is effectively identical, so there is no performance penalty to using either form. Therefore, you should choose the form of loop that is most aesthetically appealing to you, for most people that will be the for-each loop, as that has less boilerplate code.

这篇关于哪个更有效,for-each 循环还是迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆