Iterator迭代器抛出的ConcurrentModificationException(并发修改异常)的处理方式

在使用Iterator迭代器对集合中的元素进行迭代时,如果调用了集合对象的remove()方法去删除元素之后,继续使用迭代器遍历元素,会出现异常。接下来通过一个案例来演示这种异常。假设在一个集合中存储了学校所有学生的姓名,由于一个名为Annie的学生中途转学,这时就需要在迭集合时找出该元素并将其删除,具体代码如下:

import java.util.*;
public class Ex1 {
	public static void main(String[] args){
		ArrayList list = new ArrayList();
		list.add("Jack");
		list.add("Annie");
		list.add("Rose");
		list.add("Tom");
		Iterator it = list.iterator();  //ListIterator lit = list.listIterator();
										//ListIterator有add()方法
		while (it.hasNext()){
			Object obj = it.next();
			if("Annie".equals(obj)){
				list.remove(obj);				
			}
		}
		System.out.println(list);
	}
}

在这里插入图片描述
代码在运行时出现了并发修改异常(ConcurrentModificationException),这个异常是迭代器对象抛出的,出现异常的原因是集合中删除了元素会导致迭代器预期的迭代次数发生改变,导致迭代器的结果不准确。

为了解决上述问题,可以采用两种方式。

第一种方式:从业务逻辑上只想将姓名为Annie的学生删除,至于后面还有多少学生并不需要关心,只需找到该学生后跳出循环不再迭代即可,也就是在list.remove(obj);这行代码下面增加一个break;语句。代码如下:

if("Annie".equals(obj)){
	list.remove(obj);	
	break;			
}

在使用break;语句跳出循环以后,由于没有继续使用迭代器对集合中的元素进行迭代,因此,集合中删除元素对程序没有任何影响,就不会再出现异常。

第2种方式:如果需要在集合的迭代期间对集合中的元素进行删除,可以使用迭代器本身的删除方法,将list.remove(obj);这行代码替换成it.remove();即可解决这个问题,代码如下:

if("Annie".equals(obj)){
	it.remove();			
}

替换后再次运行程序,运行结果如图:
在这里插入图片描述
根据运行结果可以看出,学院Annie确实被删除了,并且没有出现异常。因此可以得出结论,调用迭代器对象的remove()方法删除元素所导致的迭代次数变化,对于迭代器对象本身来讲是可预知的。

如果想要增加元素,可以使用ListIterator特有的add方法。

Iterator和ListIterator的区别

  • Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
  • Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
  • ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_47305552/article/details/107705175