关于java:传统循环和for-each循环之间有什么区别?

What is a difference between traditional loop and for-each loop?

本问题已经有最佳答案,请猛点这里访问。

我想知道这些之间是否存在差异:

1
ArrayList<Example> list = new ArrayList<Example>

1-)

1
2
3
for(int i = 0; i < list.size(); i++) {
    list.get(i).doSomething();
}

2-)

1
2
3
for(Example example : list) {
    example.doSomething();
}

如果没有任何差异哪一个更常见或更有效?


传统的循环

1
2
3
for (int i = 0; i < list.size(); i++) {
    list.get(i).doSomething();
}
  • 允许修改列表,例如:

    • 你可以在列表的末尾添加额外的元素,它也将被迭代
  • 你知道索引

    • 可用于引用相同大小的另一个列表
    • 可用于引用上一个/下一个元素
  • 仅在RandomAccess列表中有效

    • 如果在循环的每次迭代中LinkedListget(i)将必须遍历从head/taili的所有元素
  • 仅适用于List,因为使用了List#get(int)
  • 容易出错,很多事情都可能出错,例如:

    • i = 0;而不是int i = 0; - 将引用循环之前声明的变量,循环之外可能的副作用
    • >而不是< - 循环不会执行
    • j++而不是i++ - 无限循环
    • .get(j)而不是.get(i) - 将始终获得相同的元素

For-each循环

1
2
3
for (Example example : list) {
    example.doSomething();
}
  • 不允许修改列表

    • 试图这样做很可能导致ConcurrentModificationException
  • 你不知道元素的索引

    • 你不能参考上一个/下一个元素
  • 在所有情况下都有效,因为使用了特定于集合的Iterator

    • LinkedList的情况下有效
  • 不仅适用于每个Collection,而且每次Iterable,因为使用了Iterable#iterator()

    • 您可以使用Set轻松替换List - 无需更改所需的循环
    • 您可以轻松地替换自己的类,它只需要实现Iterable
  • 更健壮(代码更少,特殊字符更少)

摘要

for-each循环赢得比分为3:2。

使用传统循环的唯一原因是:

  • 元素索引是必需的,或
  • 列表必须修改

它们基本相同,但每个(第二个)都有一定的限制。

  • 它可用于访问数组元素,但不能用于修改它们。

  • 它不适用于必须迭代的循环
    并行多个集合 - 例如,比较两个数组的元素。

  • 它只能用于单个元素访问,不能用于比较数组中的连续元素。它是一个仅向前的迭代器。如果只想访问数组的几个元素,则需要使用传统的for循环。


  • for(:)语句是只读循环。您无法在此循环中更改集合。此外,您不能使用多个元素。

    传统的for语句没有这样的限制。


    第二个适用于每种类型(可能无序)的Iterable,因为它不依赖于随机访问,即get(i)