列表遍历删除元素时报java.util.ConcurrentModificationException的原因及解决方案

 

一、问题出现

测试代码

@Test
public void listTest(){
    List<String> list =new ArrayList<>();

    list.add("a");
    list.add("b");
    list.add("c");
    
    removeList0(list);

    list.forEach(System.out::println);
}
//直接遍历删除
public void removeList0(List<String> list){

    for (String s :
            list) {
        if (s.equalsIgnoreCase("c")) {
            list.remove(s);
        }

    }

}

测试结果

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
    at java.util.ArrayList$Itr.next(ArrayList.java:859)
    at cn.hangtian.com.PackTest.removeList0(PackTest.java:499)
    at cn.hangtian.com.PackTest.listTest(PackTest.java:473)

二、问题原因

列表的foreach遍历方法中使用的迭代器中的遍历方法,迭代器还有一个修改列表计数器(modCount);

而使用列表的remove()方法修改的是列表的修改列表计数器,二者值不等导致异常。

三、问题解决

单线程中使用迭代器的remove()方法或者利用索引删除。

1、迭代器删除

测试代码

@Test
public void listTest(){

    List<String> list =new ArrayList<>();

    list.add("a");
    list.add("b");
    list.add("c");

    removeList(list);

    list.forEach(System.out::println);
}

//通过迭代器删除
public void removeList(List<String> list){
    Iterator<String> iterator = list.iterator();

    while (iterator.hasNext()){

        String s = iterator.next();

        if (s.equalsIgnoreCase("c")){
            iterator.remove();
        }
    }
}

测试结果

a

b

2、索引方式删除

测试代码

@Test
public void listTest(){
    List<String> list =new ArrayList<>();

    list.add("a");
    list.add("b");
    list.add("c");

    removeList(list);

    list.forEach(System.out::println);
}

//通过索引删除
public void removeList0(List<String> list){
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i).equalsIgnoreCase("c")) {
            list.remove(i);
        }
    }

}

测试结果

a

b

PS:多线程中请自行尝试搜索解决。😃

参考:

https://blog.csdn.net/qq_40657528/article/details/118523438

posted @ 2022-03-24 23:46  Vincent-yuan  阅读(151)  评论(0编辑  收藏  举报