List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
for (String string : list) {
if ("e".equals(string)){
list.remove(string);
}
}
当删除“e”时会报错java.util.ConcurrentModificationException,这是因为forEach循环,查看class文件可知
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
String s;
if((s = (String) iterator.next()).equals("e")) {
list.remove(s);
}
}
问题就在iterator.next(),查看源码
//当删除e时,size为5,curse为4.而删除5后size为4,curse为5还会进入循环体。
public boolean hasNext() {
return cursor != size;
}
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];
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
又因为ArrayList的remove方法只修改modCount,而没修改expectedModCount。
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
private void fastRemove(int index) {
modCount++;//在此修改modCount
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
正确的写法应该为
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
String s;
if((s = (String) iterator.next()).equals("e")) {
iterator.remove();
}
}
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();
}
}