Java 迭代器类和foreach构造之间的性能差异
我运行了以下代码,但有时在运行时会出现某种并发异常Java 迭代器类和foreach构造之间的性能差异,java,design-patterns,concurrentmodification,Java,Design Patterns,Concurrentmodification,我运行了以下代码,但有时在运行时会出现某种并发异常 ArrayList<Mob> carriers = new ArrayList<Mob>(); ArrayList<Mob> mobs = new ArrayList<Mob>(); ... for (Mob carrier : carriers){ for (Mob mob : mobs){ checkInfections (carrier, mob); } }
ArrayList<Mob> carriers = new ArrayList<Mob>();
ArrayList<Mob> mobs = new ArrayList<Mob>();
...
for (Mob carrier : carriers){
for (Mob mob : mobs){
checkInfections (carrier, mob);
}
}
ArrayList carriers=new ArrayList();
ArrayList mobs=新的ArrayList();
...
用于(移动载体:载体){
用于(暴民暴民:暴民){
检查感染(携带者、暴徒);
}
}
我对它进行了重构以解决并发性问题,但它确实给我带来了一个问题。如果我将for构造更改为迭代器模式,性能会有差异吗?foreach构造和迭代器类之间的访问级别有什么区别?除了
迭代器可以从它正在迭代的集合中删除项之外,这主要是语法上的差异。从技术上讲,增强的for
循环允许您在任何可伸缩的上循环,这至少包括集合和数组
不要担心性能差异。这种微观优化是一种无关紧要的干扰。如果需要在执行过程中删除项目,请使用迭代器
。否则,for
循环往往会被更多地使用,因为它们更具可读性,即:
for (String s : stringList) { ... }
vs:
for(迭代器iter=stringList.Iterator();iter.hasNext();){
字符串s=iter.next();
...
}
在幕后
的新样式是由编译器以迭代器的形式实现的,因此,如果您自己这样做,将不会有任何区别。您所说的“某种并发异常”很可能是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
}
}
列表=…;//无论你在哪里得到这个
for(迭代器iter=list.Iterator();iter.hasNext();){
字符串s=iter.next();
如果(…){
iter.remove();//通过迭代器删除元素
}
}
(注意:在这种情况下,您不能对循环使用foreach语法,因为您需要对迭代器进行显式访问)。您只能在诸如List、Set和Queue之类的集合上使用迭代器(接口),但对于每个循环,cab可以用于诸如集合和数组之类的所有可iterable对象。对于每个循环都更具可读性。为了变得超级迂腐,增强的for
循环允许你对任何可写的或数组进行循环,而数组不可写的可写的@ColinD我在第一段提到了这一点。实际上,我对你在第一段中的措辞很迂腐。
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
}
}