循环体中对集合进行增删时报错: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"),也是会抛出同样的异常的。
在这里插入图片描述进入ArrayList源码的909行:

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

使用ArrayListremove方法后,modCount会加一,但expectedModCount在循环开始时,二者是相等的,在通过checkForComodification方法判断后,就会抛出ConcurrentModificationException异常。
在这里插入图片描述而通过ArrayList的内部类Itr里面的remove方法去移除元素时,会将上面的两个属性重新赋值为相等,保证集合的正常操作。
在这里插入图片描述将上面的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<String> iterator = list.listIterator();如果换成Iterator<String> iterator = list.iterator();的话,则又有remove方法,没有add方法。list的两个方法在List接口中都有定义,在ArrayList中,iterator()直接返回了Itr(),而listIterator()会返回一个内部类ListItr类型,该类继承了Itr并实现了ListIterator接口。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41885819/article/details/107191848