这几天在写JAVA实验时碰到的一个和迭代器有关的问题,特意来总结一波。
起因是在使用for (Process p : processList)这样的遍历形式时,在循环体的内部遍历每一个Process类的元素p的时候,根据它的成员变量来决定是否将该元素从原集合中删除掉该元素。整个过程在IDE中编辑时IDE没有报错,但实际运行时抛出了一个ConcurrentModificationException的异常,可见这是一个Unchecked的运行时异常,编译器没有检测到错误,通过了该程序,这显然是我编写代码中产生了不规范的情况。
通过查看抛出该异常的ArrayList的源代码中的函数来找出抛出异常的原因,函数如下:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
而modCount被定义为集合结构被修改的次数,而expectedModCount就是迭代器预期的该集合被修改的次数。那么原因就找到了,就是在我的for循环中,我是一边在遍历着我的processList集合,一边又有可能在删除processList集合中的某个元素,就导致modCount经常会与expectedModCount不等,因此抛出了该异常,导致这种异常抛出的情况一般叫做迭代器并发修改这样一个情况。因此我们遍历的时候,特别是在用迭代器遍历的过程中不能并行地改变该集合的长度,也就是不能在遍历的过程中动态地增删元素。
而这样问题的解决方案也是特别简单,只需要将迭代器遍历改为一般形式的for ( ; ; )循环就行了。因此以后在编程的时候要注意使用迭代器遍历(for each)的时候不要在遍历的过程中修改集合,如果一定要修改的话可以通过使用一般形式的for循环来替换掉迭代器遍历。