先贴代码:
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
for (String temp : a) {
if ("2".equals(temp)) {
a.remove(temp);
}
}
这段代码运行会抛java.util.ConcurrentModificationException
相反使用如下代码:
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
Iterator<String> it = a.iterator();
while (it.hasNext()) {
String temp = it.next();
if ("2".equals(temp)) {
it.remove();
}
}
就会运行正常
再看:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(1);
list.add(5);
Iterator<Integer> iterator = list.iterator();
int len = list.size();
int index = 0;
while (len > 0 && index <= len) {
Integer value = iterator.next();
if (value == 1) {
iterator.remove();
}
index++;
len = list.size();
}
System.out.println(list);
也是正常的。
可以看出:iterator.remove()方法里面肯定改变了expectedModCount,使其等于modCount的值,然后再次调用iterator.next()方法的时候不会报错。
看看ArrayList里面的源码:
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
再将上述代码修改:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(1);
list.add(5);
Iterator<Integer> iterator = list.iterator();
list.add(1234);
while (iterator.hasNext()) {
Integer value = iterator.next();
if (value == 1) {
iterator.remove();
}
}
System.out.println(list);
}
会报错。
可以看出:初始化的时候iterator里面expectedModCount值已经为5了,然后执行list.add(1234),modCnt为6,但是expectedModCount还是为5。
所以:
在iterator执行的代码段里面,最好不要混合集合的add和remove操作。集合的add和remove操作,应该在iterator执行的代码端之前或之后。