一.ConcurrentModificationException异常出现的原因
请先看如下代码:
public class Test2 {
public static void main(String[] args) {
ArrayList<String> **al** = new ArrayList<String>(); //集合对象
al.add("hello");
al.add("world");
al.add("java");
Iterator<String> **ite** = al.iterator(); //迭代器对象
while(ite.hasNext()) {
String str = ite.next();
if("world".equals(str)) {
**al**.add("sql");
}
}
System.out.println(al);
异常截图:
ArrayList al = new ArrayList(); //集合对象
Iterator ite = al.iterator(); //迭代器对象
al.add(“sql”); //使用了集合对象对数组中元素进行添加
Iteration底层源码分析:
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
// prevent creating a synthetic constructor
Itr() {}
public boolean hasNext() {
return cursor != size;
}
@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];
}
Object[] elementData = ArrayList.this.elementData;
elementData 指向了底层数据结构,此时有两个引用去指向,当遍历元素时,又要添加元素,系统分不清指令,所以报异常—并发修改异常,产生原因,在使用迭代器去遍历而使用了集合对象的方法就不允许。
解决方法:
public ListIterator<E> listIterator() {
return new ListItr(0);
}
ListItr(0);为ListIterator的接口实例。
private class ListItr extends Itr
implements ListIterator { ListItr时ListIterator的内部类,ListItr继承了Itr,实现了ListIterator接口,源码分析得ListIterator方法为iterator方法得扩展,可逆向遍历元素。
解决代码(添加逆向遍历元素):
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class Test2 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>(); //集合对象
al.add("hello");
al.add("world");
al.add("java"); //Iterator<String> ite =al.iterator(); //迭代器对象
ListIterator<String>ite = al.listIterator(); //ListIterator是Iterator接口的扩展,用于解决并发修改的异常
while(ite.hasNext()){
String str = ite.next();
if("world".equals(str)){
ite.add("sql"); //使用了集合对象对数组中元素进行添加
}
}
System.out.println(al);
//逆向遍历元素
while(ite.hasPrevious()){
System.out.println(ite.previous());
}
}
}