Java遍历删除异常ConcurrentModificationException

Java遍历删除异常ConcurrentModificationException

问题描述

在java编程过程遇到一个有趣的问题:在遍历List的过程中删除其中的元素。代码如下:

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

for(String x:list){
    if(x.equals("abc"))
        list.remove(x);
}

这段代码在执行的结果会出现ConcurrentModificationException异常。但是奇怪的是这个异常并不总是会被catch。

我在windows本地tomcat部署程序后,完全没有发生异常;但将其部署到linux的云服务器后,偶尔会catch到异常,偶尔又不catch。

我猜测可能是windows本地的环境中没有符合if条件的,所以没有执行过remove,故没有catch异常。而在云服务器就有符合if条件的,所以就catch到异常了。

解决办法

不管怎么说,这个问题纯粹是没有编程没有学到家才发生的,记录下已做警示。解决办法如下:

//使用迭代器
List<String> list=new ArrayList<>();

Iterator<String> it = list.iterator();
while(it.hasNext()){
    String x = it.next();
    if(x.equals("abc")){
        it.remove();
    }
}

这种方法就可以避免出现ConcurrentModificationException异常了。但需要注意的是,这里的remove方法是Iterator对象的方法,而不是list对象的方法

问题扩展

另外,我们常用的遍历方法还有for循环,代码如下:

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

for(int i=0;i<list.size();i++){
    if(list.get(i).equals("abc"))
        list.remove(i);
}

这种方式的问题在于,删除某个元素后,list的大小发生了变化,而它的索引也在变化,所以会导致你在遍历的时候漏掉某些元素。

例如,删除了3号元素后,4号元素往前成为3号,5号往前成为4号,导致遍历第4轮得到5号元素,这就导致这次遍历漏了4号元素。

这种问题的解决办法如下:

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

for(int i=0;i<list.size();i++){
    if(list.get(i).equals("abc"))
        list.remove(i);
        i--;//手动修改索引
}

因此,不推荐使用这种方法。

猜你喜欢

转载自blog.csdn.net/a791693310/article/details/80817016