问题
在Java1.5之前,对集合的遍历习惯用下面这种方式:
for (Iterator i = c.iterator(); i.hasNext(); ) { doSomething((Element) i.next()); // (No generics before 1.5) }
对数组的遍历,习惯采用下面这种方式:
for (int i = 0; i < a.length; i++) { doSomething(a[i]); }
这些习惯用法要好于while循环,但也不完美。代迭器与索引都有些混乱。而且,它们还可能引起错误。在上面的循环中迭代器与索引都出现了三次,其中有两个地方可能带来错误,如果的确出现了这种错误,却无法保证编译器能捕获到这些错误。那么,在集合和数组的遍历中优先采用哪种方式?
解决
在集合和数组的遍历时,优先采用for-each遍历的方式,比如下面这种示例代码:
for (Element e : elements) { doSomething(e); }
for-each
循环的性能要优于传统的for循环,并且能够减少异常的发生,for-each
循环不仅可以遍历集合和数组,还可以遍历任何实现Iterable
接口的对象。同时,使用for-each
循环也有以下局限性:- 过滤:如果需要在遍历的过程中删除特定的元素,就需要用显式的迭代器,调用
remove
方法进行删除; - 转换:如果在遍历的过程中,需要转换部分元素,就需要使用迭代器或者索引,一遍设定特定的元素;
- 平行迭代:如果需要并行的遍历多个集合,就需要显式的控制迭代器和索引变量,以便所有的迭代器和索引能够同步前移。
- 过滤:如果需要在遍历的过程中删除特定的元素,就需要用显式的迭代器,调用
结论
在大多数情况下都应该使用for-each循环的方式去遍历集合和数组,只有在过滤、转换、平行迭代的时候才需要采用传统的迭代器和索引的方式进行遍历。