我运行了以下代码,但运行它时有时会遇到某种并发异常。
ArrayList<Mob> carriers = new ArrayList<Mob>();
ArrayList<Mob> mobs = new ArrayList<Mob>();
...
for (Mob carrier : carriers){
for (Mob mob : mobs){
checkInfections (carrier, mob);
}
}
我重构它来解决并发问题,但它确实引出了一个问题。如果我将for构造更改为Iterator模式,性能会有差异吗? foreach构造和Iterator类之间的访问级别差异是什么?
答案 0 :(得分:8)
差异主要是语法糖,除了Iterator
可以从正在迭代的Collection
中删除项目。从技术上讲,增强的for
循环允许您遍历任何Iterable
,其中至少包括Collection
和数组。
不要担心性能差异。这种微观优化是一种无关紧要的分心。如果您需要随时删除项目,请使用Iterator
。否则for
循环往往被更多地使用,因为它们更具可读性,即:
for (String s : stringList) { ... }
VS
for (Iterator<String> iter = stringList.iterator(); iter.hasNext(); ) {
String s = iter.next();
...
}
答案 1 :(得分:0)
在幕后,新样式for
是由编译器根据迭代器实现的,所以如果你自己这样做就没有区别了。
答案 2 :(得分:0)
您所谈论的“某种并发异常”很可能是java.util.ConcurrentModificationException
。你得到这个是因为你在迭代时不能改变列表;如果你这样做,迭代器会注意到并抛出这个异常。
如果需要在迭代时从列表中删除元素,则通过迭代器上的remove()
方法执行此操作,例如:
List<String> list = ...; // wherever you get this
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String s = iter.next();
if (...) {
iter.remove(); // Remove element through iterator
}
}
(注意:在这种情况下,不能对循环使用foreach语法,因为您需要显式访问迭代器)。
答案 3 :(得分:0)
您只能对List,Set&amp;等集合使用Iterator(接口)。队列,但每个循环cab用于可迭代的所有内容,如集合和数组。而且每个循环都更具可读性。