Java 'for each' 循环是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/85190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:07:44  来源:igfitidea点击:

How does the Java 'for each' loop work?

javaforeachsyntactic-sugar

提问by Jay R.

Consider:

考虑:

List<String> someList = new ArrayList<String>();
// add "monkey", "donkey", "skeleton key" to someList
for (String item : someList) {
    System.out.println(item);
}

What would the equivalent forloop look like without using the for eachsyntax?

如果for不使用for each语法,等效循环会是什么样子?

采纳答案by nsayer

for (Iterator<String> i = someIterable.iterator(); i.hasNext();) {
    String item = i.next();
    System.out.println(item);
}

Note that if you need to use i.remove();in your loop, or access the actual iterator in some way, you cannot use the for ( : )idiom, since the actual iterator is merely inferred.

请注意,如果您需要i.remove();在循环中使用,或以某种方式访问​​实际迭代器,则不能使用for ( : )习语,因为实际迭代器只是推断出来的。

As was noted by Denis Bueno, this code works for any object that implements the Iterableinterface.

正如丹尼斯·布埃诺 (Denis Bueno) 所指出的,这段代码适用于任何实现Iterable接口的对象。

Also, if the right-hand side of the for (:)idiom is an arrayrather than an Iterableobject, the internal code uses an int index counter and checks against array.lengthinstead. See the Java Language Specification.

此外,如果for (:)习语的右侧是一个array而不是Iterable对象,则内部代码使用 int 索引计数器并进行检查array.length。请参阅Java 语言规范

回答by toluju

The for-each loop in Java uses the underlying iterator mechanism. So it's identical to the following:

Java 中的 for-each 循环使用底层迭代器机制。所以它与以下相同:

Iterator<String> iterator = someList.iterator();

while (iterator.hasNext()) {
  String item = iterator.next();
  System.out.println(item);
}

回答by Hank

Here's an equivalent expression.

这是一个等效的表达式。

for(Iterator<String> sit = someList.iterator(); sit.hasNext(); ) {
    System.out.println(sit.next());
}

回答by Pete

It would look something like this. Very crufty.

它看起来像这样。非常粗糙。

for (Iterator<String> i = someList.iterator(); i.hasNext(); )
        System.out.println(i.next());

There is a good writeup on for eachin the Sun documentation.

Sun 文档中对每一个都有很好的说明

回答by Pete

for (Iterator<String> itr = someList.iterator(); itr.hasNext(); ) {
   String item = itr.next();
   System.out.println(item);
}

回答by EfForEffort

It's implied by nsayer's answer, but it's worth noting that the OP's for(..) syntax will work when "someList" is anythingthat implements java.lang.Iterable -- it doesn't have to be a list, or some collection from java.util. Even your own types, therefore, can be used with this syntax.

nsayer 的回答暗示了这一点,但值得注意的是,当“someList”是任何实现 java.lang.Iterable 的东西时,OP 的 for(..) 语法将起作用——它不必是一个列表,或者来自实用程序 因此,即使您自己的类型也可以使用此语法。

回答by billjamesdev

Also note that using the "foreach" method in the original question does have some limitations, such as not being able to remove items from the list during the iteration.

另请注意,在原始问题中使用“foreach”方法确实有一些限制,例如无法在迭代期间从列表中删除项目。

The new for-loop is easier to read and removes the need for a separate iterator, but is only really usable in read-only iteration passes.

新的 for 循环更易于阅读并且不需要单独的迭代器,但仅在只读迭代过程中真正可用。

回答by Mikezx6r

The construct for eachis also valid for arrays. e.g.

每个的构造也适用于数组。例如

String[] fruits = new String[] { "Orange", "Apple", "Pear", "Strawberry" };

for (String fruit : fruits) {
    // fruit is an element of the `fruits` array.
}

which is essentially equivalent of

这基本上相当于

for (int i = 0; i < fruits.length; i++) {
    String fruit = fruits[i];
    // fruit is an element of the `fruits` array.
}

So, overall summary:
[nsayer]The following is the longer form of what is happening:

所以,总体总结:
[nsayer]以下是正在发生的事情的较长形式:

for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {
  String item = i.next();
  System.out.println(item);
}

Note that if you need to use i.remove(); in your loop, or access the actual iterator in some way, you cannot use the for( : ) idiom, since the actual Iterator is merely inferred.

for(Iterator<String> i = someList.iterator(); i.hasNext(); ) {
  String item = i.next();
  System.out.println(item);
}

请注意,如果您需要使用 i.remove(); 在您的循环中,或以某种方式访问​​实际迭代器,您不能使用 for(:) 习惯用法,因为实际的迭代器只是推断出来的。

[Denis Bueno]

[丹尼斯·布埃诺]

It's implied by nsayer's answer, but it's worth noting that the OP's for(..) syntax will work when "someList" is anything that implements java.lang.Iterable -- it doesn't have to be a list, or some collection from java.util. Even your own types, therefore, can be used with this syntax.

nsayer 的回答暗示了这一点,但值得注意的是,当“someList”是任何实现 java.lang.Iterable 的东西时,OP 的 for(..) 语法将起作用——它不必是一个列表,或者来自实用程序 因此,即使您自己的类型也可以使用此语法。

回答by Ryan Delucchi

The Java "for-each" loop construct will allow iteration over two types of objects:

Java“for-each”循环结构将允许对两种类型的对象进行迭代:

  • T[](arrays of any type)
  • java.lang.Iterable<T>
  • T[](任何类型的数组)
  • java.lang.Iterable<T>

The Iterable<T>interface has only one method: Iterator<T> iterator(). This works on objects of type Collection<T>because the Collection<T>interface extends Iterable<T>.

Iterable<T>接口只有一种方法:Iterator<T> iterator(). 这适用于类型的对象,Collection<T>因为Collection<T>接口扩展了Iterable<T>.

回答by MRocklin

Here is an answer which does not assume knowledge of Java Iterators. It is less precise, but it is useful for education.

这是一个不假设您了解 Java 迭代器的答案。它不太精确,但对教育很有用。

While programming we often write code that looks like the following:

在编程时,我们经常编写如下所示的代码:

char[] grades = ....
for(int i = 0; i < grades.length; i++) {   // for i goes from 0 to grades.length
    System.out.print(grades[i]);           // Print grades[i]
}

The foreach syntax allows this common pattern to be written in a more natural and less syntactically noisy way.

foreach 语法允许以更自然和更少语法干扰的方式编写这种常见模式。

for(char grade : grades) {   // foreach grade in grades
    System.out.print(grade); // print that grade
}

Additionally this syntax is valid for objects such as Lists or Sets which do not support array indexing, but which do implement the Java Iterable interface.

此外,此语法对于不支持数组索引但实现 Java Iterable 接口的对象(例如 Lists 或 Sets)有效。