并行修改异常的产生和解决(昆山学习笔记)

并行修改异常ConcurrentModificationException  。

 这种问题有时候会出现在面试题中。

下面用代码的形式演示:

                                        1.如何出现的并行修改异常?

                                        2.是如何解决并行修改异常?

异常的出现:(用我理解的白话解释)List集合中有n个元素,List集合请求Iterator迭代器帮助它迭代出集合中的元素,迭代器答应了List的请求,然后去执行迭代任务了。就在这时候,List突然又想往集合中添加一个元素(关系户),但是迭代器(Iterator)已经开始了迭代任务了,迭代器并不知道List往自己集合重安排了一个新的元素。这时候 Iterator的迭代任务和List添加任务 发生了 冲突和异常 ,简而言之,list想添加一个元素,但是没有事先通知正在执行迭代任务iterator迭代器,,所以导致了异常。

异常的解决:因为List集合使用add()方法添加元素,没办法让迭代器iterator知道。 所以 普通的迭代器(Iterator)无法完成 List的要求,所以应当使用List自带的ListIterator迭代器,这是List集合特有的迭代器获取方法,ListIterator中含有add()方法,可以用迭代器的add()方法 ,为List集合添加元素,这样就避免了异常。

修改的地方:本来是List + Iterator   使用List集合中的add()方法添加元素。   

                    变成了List + ListIterator  使用ListIterator迭代器中的add()方法添加元素。

  

代码直接粘贴运行即可: 

import java.util.ArrayList;

import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;


public class Main {


public static void main(String[] args) {
List list = new ArrayList();
list.add("a"); 
list.add("b"); 
list.add("world");
list.add("c"); 

list.add("d"); 

// 下面的操作会出现:并行修改错误。

Iterator itr = list.iterator() ; 
while(itr.hasNext()){
//System.out.println(itr.next());//输出为:a b c d 。
//这个输出的 a b c d 不是String 类型的 , 因为 Object obj = new String("a");
/*例题如下:
*  判断里面是否有"world"这个元素,如果有,我就再添加一个"javaee"元素,请写代码实现。
*/

//第一步: 将 集合中的 Object类对象 转换成 String类型 。 
String str = (String)itr.next();
if(str.equals("world")){

//list.add(2,"javaee");//错误操作。

//出现错误: ConcurrentModificationException
//错误解释: list本来告诉迭代器有 n个元素需要操作,当list又想添加一个元素进行操作,也就是元素个数变为 n+1 个 ,但是这个情况 list没有告诉迭代器itr,所以itr在操作的时候没有完成list的意愿,所以导致了出现异常。


//解决方法:当满足特定条件时,list想要添加一个元素到集合中,这时因为 list去添加这个元素,无法让迭代器知道这个操作,所以 我们就不对list进行操作了,我们只对迭代器itr进行操作,这样我们的操作,迭代器就知道了,通过迭代器改变list集合中元素组成。

//也就是 将本来 通过list 添加 新元素,改变为 通过 迭代器itr进行操作添加 。 这样 list的 想法都统一了,就不会出现异常了。 


}

}


//下面的操作不会出现异常:因为是通过迭代器为list进行添加元素操作的。

ListIterator lit = list.listIterator();//这里要特别注意 
// 这个没有使用多态,listlterator中有add这个方法,所以lit可以调用。
//Iterator lit = list.listIterator(); 虽然是使用了多态的特性,但是 Iterator 接口中不包括 add这个方法,lit不能调用出add方法。
while(lit.hasNext()){
 String str = (String)lit.next() ;
 if("world".equals(str)){
 lit.add("javaee");
 }
}
//用迭代器添加 list需要添加的 元素 , 添加完后 list中就有了 需要添加的 元素 。
System.out.println(list);//[a, b, world, javaee, c, d]
}


}


//正确的代码,不发生并行修改错误的代码: 

题目:搜索集合中是否有"world"字符串,如果有,那么就往集合中添加"javaee"字符串,否则,不添加。

代码如下: 

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Main {

	public static void main(String[] args) {
		//查看集合中是否有 "world" ,如果有,那么添加 "javaee"。
		List list = new ArrayList() ;
		list.add("a");
		list.add("b");
		list.add("world");
		list.add("c");
		list.add("d");
		ListIterator lit = list.listIterator(); //为了不出现 并行修改异常错误 ,所以使用了ListIterator这个List特有的迭代器,然后使用其中的add方法,用迭代器为List集合进行元素添加。
		while(lit.hasNext()){
			//lit.next()是Object类对象。 
			String str = (String)lit.next() ;
			if("world".equals(str)){
				lit.add("javaee");
			}
		}
		System.out.println(list);//输出结果为:[a, b, world, javaee, c, d]

	}

}

猜你喜欢

转载自blog.csdn.net/Ameir_yang/article/details/80845108