sfu*_*ger 81
假设这就是你的意思:
// traditional for loop
for (int i = 0; i < collection.size(); i++) {
T obj = collection.get(i);
// snip
}
// using iterator
Iterator<T> iter = collection.iterator();
while (iter.hasNext()) {
T obj = iter.next();
// snip
}
// using iterator internally (confirm it yourself using javap -c)
for (T obj : collection) {
// snip
}
Run Code Online (Sandbox Code Playgroud)
对于没有随机访问的集合(例如TreeSet,HashMap,LinkedList),Iterator更快.对于数组和ArrayLists,性能差异应该可以忽略不计.
编辑:我相信微基准测试是非常邪恶的根源,就像早期优化一样.但话说回来,我觉得对这些相当琐碎的事情的影响感觉很好.因此,我进行了一个小测试:
除了"with with counter"与LinkedList之外的所有结果都相似.所有其他五个花费不到20毫秒来迭代整个列表.使用list.get(i)
上一个LinkedList 100,000次时间超过2分钟(!)来完成的(60,000倍慢).哇!:)因此,最好使用迭代器(显式或隐式使用每个),特别是如果你不知道你处理的列表的类型和大小.
Sva*_*nte 22
使用迭代器的第一个原因是显而易见的正确性.如果您使用手动索引,可能会出现非常无害的逐个错误,只有在您仔细观察时才能看到这些错误:您是从1开始还是从0开始?你完成了length - 1
吗?你使用<
或<=
?如果使用迭代器,则更容易看出它实际上正在迭代整个数组."说你做什么,做你说的话."
第二个原因是对不同数据结构的统一访问.可以通过索引有效地访问数组,但最好通过记住访问的最后一个元素来遍历链接列表(否则您将获得" Shlemiel the painter ").哈希映射更复杂.通过提供来自这些和其他数据结构的统一接口(例如,您也可以进行树遍历),您可以再次获得明显的正确性.遍历逻辑必须只实现一次,使用它的代码可以简洁地"说出它做什么,并按照它说的做".
在大多数情况下,性能是相似的。
但是,每当代码接收到一个List并在其上循环时,就会发生一种众所周知的情况:
对于所有未实现RandomAccess的List实现,Iterator会更好(示例:LinkedList)。
原因是对于这些列表,按索引访问元素不是固定时间的操作。
因此,您也可以将Iterator视为更健壮的(针对实现细节)。
与往常一样,性能不应成为隐藏可读性的问题。
java5 foreach循环在这方面很受欢迎:-)