java.util.ConcurrentModification
2019-12-02 本文已影响0人
禾叶super
在ArrayList使用for循环迭代时,remove元素,会出现ConcurrentModificationException异常 。
public class Test2 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(5);
for (Integer a:list) {
if (a == 1){
list.remove(i);
}
System.out.println(a);
}
}
}
image.png
出现异常的原因是什么
/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
private void fastRemove(int index) {
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
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
让我们看一下源码,list的remove操作的方法中modCount++ ,modCount值自增1,致使checkForComodification()方法中expectedModCount不等于modCount ,因此抛出ConcurrentModificationException异常。
解决方案:引入Java 8的新特性stream
public class Test2 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
list.add(5);
List<Integer> list1 = list.stream().filter(i -> i!=1).collect(Collectors.toList());
for (Integer a:list1) {
System.out.println(a);
}
}
}
想了解更多stream特性,参考如下链接。
参考链接:https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/index.html