传统循环和 for-each 循环有啥区别? [复制]
Posted
技术标签:
【中文标题】传统循环和 for-each 循环有啥区别? [复制]【英文标题】:What is a difference between traditional loop and for-each loop? [duplicate]传统循环和 for-each 循环有什么区别? [复制] 【发布时间】:2016-02-08 12:01:03 【问题描述】:我想知道这些之间是否有区别:
ArrayList<Example> list = new ArrayList<Example>
1-)
for(int i = 0; i < list.size(); i++)
list.get(i).doSomething();
2-)
for(Example example : list)
example.doSomething();
如果没有任何区别,哪一种更常见或更有效?
【问题讨论】:
有什么区别? 过早优化:不要。只是...不要。如果您没有速度问题,请不要解决它。在 99.9% 的情况下,您不会注意到两者之间的区别 - 除了显而易见的情况外,您有一个索引(并且没有迭代器)并且它仅适用于具有 get(x) 方法的方法,而其他你没有索引,一个迭代器,它适用于任何集合。 第二种效率更高。因为每个 .get(i) 都会启动一个随机访问搜索。 @Reinard 可能是的,具体取决于迭代的列表。示例中的ArrayList
没有速度差异,但 LinkedList
会显示出明显的差异。
@JaroslawPawlak 您应该始终使用 for-each 循环,除非您出于某种原因需要索引。 (或者在 Java 8 中,您可以使用流。)并不是因为它更快(通常不是),而是因为它更易于阅读。
【参考方案1】:
传统循环
for (int i = 0; i < list.size(); i++)
list.get(i).doSomething();
允许修改列表,例如:
您可以在列表末尾添加额外元素,它也会被迭代
你知道索引
可用于引用另一个相同大小的列表
可用于引用上一个/下一个元素
仅在RandomAccess
列表中有效
在循环的每次迭代中LinkedList
的情况下,get(i)
必须遍历从head/tail
到i
的所有元素
仅适用于List
,因为使用了List#get(int)
容易出错,很多事情都可能出错,例如:
i = 0;
而不是 int i = 0;
- 将引用循环前声明的变量,可能会在循环外产生副作用
>
而不是 <
- 循环不会执行
j++
而不是 i++
- 无限循环
.get(j)
而不是 .get(i)
- 将始终获得相同的元素
for-each 循环
for (Example example : list)
example.doSomething();
不允许修改列表
尝试这样做很可能会导致ConcurrentModificationException
你不知道元素的索引
您不能引用上一个/下一个元素
在所有情况下都有效,因为使用特定于集合的Iterator
在LinkedList
的情况下有效
不仅适用于每个Collection
,而且适用于每个Iterable
,因为使用了Iterable#iterator()
您可以轻松地将 List
替换为 Set
- 无需更改循环
你可以很容易地用你自己的类替换,它只需要实现Iterable
更健壮(更少的代码,更少的特殊字符)
总结
for-each
循环以 3 : 2 获胜。
使用传统循环的唯一原因是:
元素的索引是必需的,或者 列表需要修改【讨论】:
【参考方案2】:它们基本相同,但for-each(第二个)有一定的限制。
它可以用于访问数组元素,但不能用于修改它们。
对于必须迭代的循环,它不可用 多个集合并行——例如,比较两个数组的元素。
它只能用于单个元素的访问,不能用于比较数组中的连续元素。它是一个只进迭代器。如果您只想访问数组的少数元素,则需要使用传统的 for 循环。
【讨论】:
@Point 1:您可以通过调用可变方法来修改数组元素。 (或者您需要指定“修改”的含义)我想您的意思是不能修改数组(或Iterable
)本身。【参考方案3】:
第二个适用于所有类型的(可能是无序的)Iterable,因为它不依赖于随机访问,即get(i)
。
【讨论】:
【参考方案4】:for(:)
语句是一个只读循环。您不能在此循环中更改集合。此外,您不能使用多个元素。
传统的for
语句没有这样的限制。
【讨论】:
以上是关于传统循环和 for-each 循环有啥区别? [复制]的主要内容,如果未能解决你的问题,请参考以下文章