【问题标题】:Does Java's foreach loop preserve order?Java 的 foreach 循环是否保持顺序?
【发布时间】:2016-05-02 20:08:42
【问题描述】:

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

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

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

【问题讨论】:

  • 简短回答:是的,对于数组它确实如此。 (有点)更长的答案:取决于您迭代的对象
  • @ParkerHalo Strings 怎么样?
  • 问题:为什么要通过只使用循环来应用排序(或任何其他修改)(无论您是直接使用 foreach 还是迭代器)?
  • @Celeritas 也许我的评论具有误导性:对于所有数组(和数组列表),顺序保持不变。对于其他列表/集合,这可能不是真的!
  • @ParkerHalo For other lists ... this might not be true! 你说得对,它可能不是真的,但是列表的定义包含一个指定/确定的顺序,所以如果它不是真的某些列表我不会再称它为列表了。 :)

标签: java foreach


【解决方案1】:

是的。顺序没有改变。这适用于实现 for 循环使用的 iterator interface 的所有类型的 Java Collection Framework 集合。如果要对数组进行排序,可以使用Arrays.sort(names)

【讨论】:

  • 还要注意 forEach 为流更改的语义 - 在这种情况下,如果您想保证顺序,您将需要使用 forEachOrdered
【解决方案2】:

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

它可以用来循环数组和Iterable的实例。

  • 对于数组,迭代的顺序将始终保持不变,并且在运行之间保持一致。这是因为它相当于一个简单的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 以查看顺序是否一致。例如it is explicitely specified that for List, the iterator retains the order:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 2013-01-04
    • 2020-06-24
    • 2017-12-04
    • 1970-01-01
    相关资源
    最近更新 更多