循环体中对集合进行增删时报错:java.util.ConcurrentModificationException

先看一段代码:

 @Test
 public void test02(){
     List<String> list = new ArrayList<>(8);
     list.add("tom");
     list.add("jack");
     list.add("marry");
     list.add("wuwl");
     for(String string:list){
         if("wuwl".equals(string)){
             list.remove(string);
         }
     }
 }

上面代码在运行过程中,肯定会抛出java.util.ConcurrentModificationException异常的,将list.remove(string);替换成list.add("gg"),也是会抛出同样的异常的。
循环体中对集合进行增删时报错:java.util.ConcurrentModificationException_第1张图片进入ArrayList源码的909行:

final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}

使用ArrayListremove方法后,modCount会加一,但expectedModCount在循环开始时,二者是相等的,在通过checkForComodification方法判断后,就会抛出ConcurrentModificationException异常。
循环体中对集合进行增删时报错:java.util.ConcurrentModificationException_第2张图片而通过ArrayList的内部类Itr里面的remove方法去移除元素时,会将上面的两个属性重新赋值为相等,保证集合的正常操作。
循环体中对集合进行增删时报错:java.util.ConcurrentModificationException_第3张图片将上面的demo改成下面的代码即可正常运行:

@Test
public void test03(){

    List<String> list = new ArrayList<>(8);
    list.add("tom");
    list.add("jack");
    list.add("marry");
    list.add("wuwl");
    ListIterator<String> iterator = list.listIterator();
    while(iterator.hasNext()){
        if("wuwl".equals(iterator.next())){
            iterator.remove();
            iterator.add("gg");
        }
    }
    System.out.println(list);
}

ListIterator iterator = list.listIterator();如果换成Iterator iterator = list.iterator();的话,则又有remove方法,没有add方法。list的两个方法在List接口中都有定义,在ArrayList中,iterator()直接返回了Itr(),而listIterator()会返回一个内部类ListItr类型,该类继承了Itr并实现了ListIterator接口。
循环体中对集合进行增删时报错:java.util.ConcurrentModificationException_第4张图片

你可能感兴趣的:(源码的秘密)