为了账号安全,请及时绑定邮箱和手机立即绑定

Java中传统for循环与Iterator / foreach的性能

Java中传统for循环与Iterator / foreach的性能

素胚勾勒不出你 2019-11-26 15:06:47
在遍历ArrayList,HashMap和其他集合时比较传统的for循环与Iterator是否有任何性能测试结果?或者只是为什么我应该在循环中使用Iterator,反之亦然?
查看完整描述

3 回答

?
梦里花落0921

TA贡献1772条经验 获得超6个赞

假设这是您的意思:


// 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

}

对于没有随机访问权限的集合(例如TreeSet,HashMap,LinkedList),Iterator的速度更快。对于数组和ArrayList,性能差异应该可以忽略不计。


编辑:我相信微基准测试是邪恶的根源,就像早期的优化一样。但是话又说回来,我觉得对这样琐碎的事情的含义有感觉是一件好事。因此,我进行了一个小测试:


分别遍历LinkedList和ArrayList

带有100,000个“随机”字符串

总结它们的长度(只是为了避免编译器优化整个循环)

使用所有3种循环样式(迭代器,每种,用于带计数器)

除LinkedList“带有计数器”外,其他所有结果均相似。所有其他五个在不到20毫秒的时间内遍历整个列表。使用list.get(i)上一个LinkedList 100,000次时间超过2分钟(!)来完成(慢6万倍)。哇!:)因此,最好使用迭代器(显式或隐式地为每个迭代器使用),尤其是如果您不知道要处理的列表的类型和大小时。


查看完整回答
反对 回复 2019-11-26
?
守着星空守着你

TA贡献1799条经验 获得超8个赞

使用迭代器的第一个原因是显而易见的正确性。如果您使用手动索引,那么如果仔细观察,可能会发现非常无害的一一错误:您是从1开始还是从0开始?你完成了length - 1吗?您使用<还是<=?如果使用迭代器,则很容易看到它确实在迭代整个数组。“说你做什么,说什么。”

第二个原因是对不同数据结构的统一访问。可以通过索引有效地访问数组,但是最好记住已访问的最后一个元素来遍历链接列表(否则,您将获得“ 画家莱姆尼尔 ”)。哈希图甚至更加复杂。通过提供来自这些数据结构和其他数据结构的统一接口(例如,您也可以进行树遍历),您将再次获得明显的正确性。遍历逻辑只需要实现一次,并且使用它的代码可以简洁地“说出它做什么,然后按照它说的去做”。


查看完整回答
反对 回复 2019-11-26
  • 3 回答
  • 0 关注
  • 766 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信