4

我正在运行以下代码,但有时在运行它时会遇到某种并发异常。

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 类之间的访问级别有什么区别?

4

4 回答 4

8

区别主要在于语法糖,只是Iterator可以从Collection它正在迭代的对象中删除项目。从技术上讲,增强for的循环允许您循环任何 s Iterable,其中至少包括Collections 和数组。

不要担心性能差异。这种微优化是一种无关紧要的干扰。如果您需要随时删除项目,请使用Iterator. 否则for,循环往往会被更多地使用,因为它们更具可读性,即:

for (String s : stringList) { ... }

与:

for (Iterator<String> iter = stringList.iterator(); iter.hasNext(); ) {
  String s = iter.next();
  ...
}
于 2010-07-06T02:38:12.143 回答
0

在幕后,新样式for是由编译器根据迭代器实现的,因此如果您自己这样做也没有什么区别。

于 2010-07-06T06:03:12.647 回答
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 语法,因为您需要显式访问迭代器)。

于 2010-07-06T06:52:37.573 回答
0

您只能在 List、Set 和 Queue 等集合上使用 Iterator(interface),但对于每个循环可用于所有可迭代的内容,例如 Collections 和 Array。而且对于每个循环都更具可读性..

于 2013-06-02T13:46:06.810 回答