苏州学做网站,网站建设添加汉语,滨州做网站的电话,五合一网站做优化好用吗java迭代集合出现并发修改异常(ConcurrentModificationException)的原因以及解决方案
一. 什么时候会出现并发修改异常?
这里先看需求 : 定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马
很显然要求我们先创建一个集合并进行…java迭代集合出现并发修改异常(ConcurrentModificationException)的原因以及解决方案
一. 什么时候会出现并发修改异常?
这里先看需求 : 定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马
很显然要求我们先创建一个集合并进行迭代 , 当迭代到猪八戒,的时候插入白龙马
代码实现
public static void main(String[] args) {//需求:定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马ArrayListString list new ArrayList();list.add(唐僧);list.add(孙悟空);list.add(猪八戒);list.add(沙僧);IteratorString iterator list.iterator();while(iterator.hasNext()){String element iterator.next();if (猪八戒.equals(element)){list.add(白龙马);}}System.out.println(list);}运行后报错 这里报了一个ConcurrentModificationException 也就是并发修改异常
二. 产生原因
我们来进入源码分析一下 首先我们来进入 iterator() 方法 , 这里iterator() 是返回了了一个新对象也就是Itr() , 那我们再来看一下Itr()方法 public IteratorE iterator() {return new Itr();}Itr() , 光观察Itr()好像并没有发现异常的原因 , 那我们再看next()方法 private class Itr implements IteratorE {int cursor; // index of next element to returnint lastRet -1; // index of last element returned; -1 if no suchint expectedModCount modCount;// prevent creating a synthetic constructorItr() {}public boolean hasNext() {return cursor ! size;} next() , 这里在运行next()的时候会先调用checkForComodification();方法那我们就先来查看这个方法 SuppressWarnings(unchecked)public E next() {checkForComodification();int i cursor;if (i size)throw new NoSuchElementException();Object[] elementData ArrayList.this.elementData;if (i elementData.length)throw new ConcurrentModificationException();cursor i 1;return (E) elementData[lastRet i];}checkForComodification() , 很显然这里判断了modCount 与 expectedModCount是否相等 , 如果不相等则抛出throw new ConcurrentModificationException(); 也就是并发修改异常 modCount: 实际操作次数 expectedModCount:预期操作次数 final void checkForComodification() {if (modCount ! expectedModCount)throw new ConcurrentModificationException();}那么通过上面的分析我们就知道了产生问题的原因是什么 , 也就是modCount 与 expectedModCount并不相等 那是什么导致modCount 与 expectedModCount不相等的呢 ? 在代码中我们调用了一个add方法 , 那么add是否就是产生问题的原因 add() , 还是和刚才一样 , 进入add()底层源码我们来找一下原因 public boolean add(E e) {modCount;add(e, elementData, size);return true;}到这里就一目了然了我们在调用add的时候会对modCount , 在modCount自增之后 , 我们再调用next()方法就会导致modCount 与 expectedModCount不相等 , 从而抛出异常
三. 解决方法
ArrayList中的方法:ListIterator listIterator()
public class Demo03Iterator {public static void main(String[] args) {//需求:定义一个集合,存储 唐僧,孙悟空,猪八戒,沙僧,遍历集合,如果遍历到猪八戒,往集合中添加一个白龙马ArrayListString list new ArrayList();list.add(唐僧);list.add(孙悟空);list.add(猪八戒);list.add(沙僧);//IteratorString iterator list.iterator();ListIteratorString listIterator list.listIterator();while(listIterator.hasNext()){String element listIterator.next();if (猪八戒.equals(element)){listIterator.add(白龙马);}}System.out.println(list);}
}