是否有机会在使用经典循环时发生并发修改异常?
import java.util.*;
class IterTest{
public static void main(String[] args){
List<Integer> nums = new ArrayList<>();
nums.add(18);
nums.add(1);
nums.add(14);
nums.add(13);
System.out.println("Nums ->"+nums);
int len = nums.size();
for(int index=0;index < len ;index++){
System.out.println(" Current >>"+nums.get(index));
System.out.println(" Removing >>"+nums.remove(index));
}
}
}
不,没有机会。使用迭代器时可能会发生同时修改异常,请查看Java中的故障安全和失败的迭代器
否,此代码不会给出ConcurrentModificationException
。当收藏的视图被从其下方更改而来时,通常会发生这种例外。当Iterator
迭代(在增强的语句中隐含使用)或获得subList()
,修改基础列表,然后继续使用Sublist。
但是,此代码将遇到与"破坏"循环的相同条件,除非会抛出不同的例外。循环范围基于列表的初始大小。但是,循环主体从列表中删除元素,因此代码最终将在列表的边界之外索引,从而导致IndexOutOfBoundsException
。
如何修复此代码取决于您要做什么。最初,使用列表索引而不是Iterator
,避免使用ConcurrentModificationException
似乎很明智。但是,如果列表在循环过程中进行了结构修改(即添加或删除元素),则需要仔细调整索引和环界,否则可能会跳过元素,重复或IndexOutOfBoundsException
。
否,正如其他答案所建议的那样,ConcurrentModificationException
不会在给定代码中发生。
那么何时发生contrentModificationException?
在单线环境中,通常会在您使用迭代器循环收集并同时修改它时发生。
为什么?
如果您检查迭代器实现的源代码,则每当您使用任何迭代器(例如Next Next(),remove())时,它总是会进行checkForcomodification()。例如,arraylist.java中该方法的代码是:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
其中 modCount 是在ArrayList类级别维护的静态变量,该变量表示该列表已在结构上修改的次数。预期的修改计数预期modcount 保持在迭代器类级别,最初等于modCount。
。因此,只要预期的修改数与实际完成的修改不匹配,您就会得到异常。
在您的情况下,您尚未使用任何此事,因此不会进行共同修改的检查,因此您将无法获得ConcurrentModificationException
。
注意:如本答案所述,您将获得IndexOutOfBoundsException
,因为您已经在循环中检查了index < len
,并且len
初始化为数组的初始大小。一个简单的解决方案是:
for(int index=0;index < nums.size;index++)