Java 的 foreach 循环是否保留顺序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35010846/
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 16:13:47  来源:igfitidea点击:

Does Java's foreach loop preserve order?

javaforeach

提问by Celeritas

Does Java's foreach loop start at the first object and in a linear fashion work it's way to the end? For example

Java 的 foreach 循环是否从第一个对象开始并以线性方式工作到最后?例如

String[] names = new String[] {"Zoe", "Bob", "Charlie", "Alex"};
for(String name : names) {
  //do stuff...
}

Is the string "Zoe" always processed first, followed by "Bob" etc? No sorting happens? I've tested it out myself and haven't found any but I need a guarantee and couldn't find anything in the docs.

字符串“Zoe”是否总是先处理,然后是“Bob”等?没有排序发生?我自己测试过了,没有找到,但我需要一个保证并且在文档中找不到任何东西。

采纳答案by Simulant

Yes. The order is not changed. This applies to all types of collections of the Java Collection Frameworkimplementing the iterator interfacethat is used by the for-loop. If you want to sort your Array, you can use Arrays.sort(names)

是的。顺序没有改变。这适用于实现for 循环使用的迭代器接口Java 集合框架的所有类型的集合。如果要对数组进行排序,可以使用Arrays.sort(names)

回答by Tunaki

The enhanced forloop is specified in JLS 14.14.2, where its equivalent code is written.

增强for循环在 JLS 14.14.2 中指定,其中编写了等效代码。

It can be used to loop over arrays and instances of Iterable.

它可用于循环遍历数组和Iterable.

  • For an array, the order of iteration will be always preserved and be consistent between runs. This is because it is equivalent to a simple forloop with an index going from the beginning of the array to its end.

    The enhanced for statement is equivalent to a basic for statement of the form:

    T[] #a = Expression;
    L1: L2: ... Lm:
    for (int #i = 0; #i < #a.length; #i++) {
        {VariableModifier} TargetType Identifier = #a[#i];
        Statement
    }
    

    #aand #iare automatically generated identifiers that are distinct from any other identifiers (automatically generated or otherwise) that are in scope at the point where the enhanced for statement occurs.

  • For an Iterable, it will follow the order of the corresponding Iterator(retrieved by calling Iterable.iterator()), that may or may not be consistent between runs.

    The enhanced for statement is equivalent to a basic for statement of the form:

    for (I #i = Expression.iterator(); #i.hasNext(); ) {
    {VariableModifier} TargetType Identifier =
        (TargetType) #i.next();
        Statement
    }
    

    #iis an automatically generated identifier that is distinct from any other identifiers (automatically generated or otherwise) that are in scope (§6.3) at the point where the enhanced for statement occurs.

    You should refer to the Javadoc of each type to see if an order is consistent or not. For example, it is explicitely specified that for List, the iterator retains the order:

    Returns an iterator over the elements in this list in proper sequence.

    While it is explicitely specified that for Set, the order is unspecified (unless an extra guarantee is made):

    The elements are returned in no particular order (unless this set is an instance of some class that provides a guarantee).

  • 对于数组,迭代顺序将始终保留并在运行之间保持一致。这是因为它相当于一个简单的for循环,其中的索引从数组的开头到结尾。

    增强的 for 语句等效于以下形式的基本 for 语句:

    T[] #a = Expression;
    L1: L2: ... Lm:
    for (int #i = 0; #i < #a.length; #i++) {
        {VariableModifier} TargetType Identifier = #a[#i];
        Statement
    }
    

    #a#i是自动生成的标识符,它们不同于在增强的 for 语句发生的点范围内的任何其他标识符(自动生成的或以其他方式生成的)。

  • 对于Iterable,它将遵循相应的顺序Iterator(通过调用 检索Iterable.iterator()),这在运行之间可能一致,也可能不一致。

    增强的 for 语句等效于以下形式的基本 for 语句:

    for (I #i = Expression.iterator(); #i.hasNext(); ) {
    {VariableModifier} TargetType Identifier =
        (TargetType) #i.next();
        Statement
    }
    

    #i是一个自动生成的标识符,它不同于在增强的 for 语句发生点的范围内(第 6.3 节)的任何其他标识符(自动生成的或以其他方式生成的)。

    您应该参考每种类型的 Javadoc 以查看订单是否一致。例如,明确指定 for List,迭代器保留顺序

    以适当的顺序返回此列表中元素的迭代器。

    虽然明确指定了 for Set,但顺序未指定(除非做出额外保证)

    元素没有特定的顺序返回(除非这个集合是提供保证的某个类的实例)。