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

sha*_*nks 14 java

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

ArrayList<Example> list = new ArrayList<Example>
Run Code Online (Sandbox Code Playgroud)

1-)

for(int i = 0; i < list.size(); i++) {
    list.get(i).doSomething();
}
Run Code Online (Sandbox Code Playgroud)

2-)

for(Example example : list) {
    example.doSomething();
}
Run Code Online (Sandbox Code Playgroud)

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

Jar*_*lak 22

传统的循环

for (int i = 0; i < list.size(); i++) {
    list.get(i).doSomething();
}
Run Code Online (Sandbox Code Playgroud)
  • 允许修改列表,例如:
    • 你可以在列表的末尾添加额外的元素,它也将被迭代
  • 你知道索引
    • 可用于引用相同大小的另一个列表
    • 可用于引用上一个/下一个元素
  • 仅在RandomAccess列表中 有效
    • 如果LinkedList在循环的每次迭代中,get(i)将不得不迭代从head/tailto 开始的所有元素i
  • 仅适用于List以后List#get(int)使用
  • 容易出错,很多事情都可能出错,例如:
    • i = 0;而不是int i = 0;- 将引用循环之前声明的变量,循环之外可能的副作用
    • >而不是<- 循环不会执行
    • j++而不是i++- 无限循环
    • .get(j)而不是.get(i)- 将始终获得相同的元素

For-each循环

for (Example example : list) {
    example.doSomething();
}
Run Code Online (Sandbox Code Playgroud)
  • 不允许修改列表
    • 试图这样做很可能会导致 ConcurrentModificationException
  • 你不知道元素的索引
    • 你不能参考上一个/下一个元素
  • 在所有情况下都有效,因为Iterator特定于集合的 用途
    • 有效的情况下 LinkedList
  • 不仅与每一个作品Collection,但每Iterable因为Iterable#iterator()使用
    • 你可以很容易地更换ListSet-不改变所需的循环
    • 你可以轻松地用自己的类替换,它只需要实现 Iterable
  • 更健壮(代码更少,特殊字符更少)

摘要

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

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

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