我正在尝试从循环内的ArrayList中删除一个元素。
没关系。
ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
for(Integer i: list){
if(i == 2)
list.remove(i);
}
但这不是,并抛出concurrentMOdificationException。
ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(1, 2, 3));
for(Integer i: list){
list.remove(i);
}
我不明白为什么。
我刚刚添加了另一个元素,它也不正常(throw concurrentMOdificationException)。
ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4));
System.out.println(list);
for (Integer i : list) {
if (i == 2)
list.remove(i);
}
答案 0 :(得分:4)
使用Iterator类而不是for-each循环。
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
Integer i = it.next();
it.remove();
}
http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificationException.html
例如,一个线程通常不允许修改Collection而另一个线程正在迭代它。通常,在这些情况下,迭代的结果是不确定的。如果检测到此行为,某些Iterator实现(包括JRE提供的所有通用集合实现的实现)可能会选择抛出此异常。执行此操作的迭代器称为失败快速迭代器,因为它们快速而干净地失败,而不是在未来的未确定时间冒着任意的,非确定性行为的风险。
请注意,此异常并不总是表示某个对象已被另一个线程同时修改。如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常。例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。
答案 1 :(得分:0)
当使用这种性质的for
循环时,您必须了解一些事情。它实际上是在引擎盖下使用java.util.Iterator
。这个迭代器将使用next()
方法来确定何时应该停止迭代,并使用hasNext()
方法来检索下一个元素。
踢球者只有next()
检查并发修改 - hasNext()
不执行检查。在第一种情况下,您等到第二次循环迭代从列表中删除2
,然后下一次迭代找到列表的结尾并退出。在第二种情况下,在第一次迭代期间从列表中删除1
,下一次迭代在尝试检索下一个元素时抛出异常。