【问题标题】:java list java.util.ConcurrentModificationException [duplicate]java列表java.util.ConcurrentModificationException [重复]
【发布时间】:2016-01-23 16:53:18
【问题描述】:

我有这样的代码和平。
我知道这必须给我 ConcurrentModificationException
我必须使用迭代器或克隆列表或只使用 for 循环。

问题是这段代码运行没有问题,并且 ls.remove 可以在 0-2 之间的任何索引处工作。
现在 if 我将 s.equals("two") 更改为 s.equals("one") 或列表中除“two”之外的任何其他内容"
我将始终按预期获得 ConcurrentModificationException。

此外,如果我取消注释 ls.add("four") 行,无论 s.equals() 是什么,我都会遇到 ConcurrentModificationException。

并且 我的问题是为什么会发生这种情况以及为什么下面的代码运行良好而 ConcurrentModificationException 仅适用于 s.equals("two") ?

import java.util.*;
import java.util.List;

    public class Test {

    public static void main(String args[]) {

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

        ls.add("one");
        ls.add("two");
        ls.add("three");
        //ls.add("four");

        for(String s : ls) {
            if(s.equals("two")) {
                ls.remove(0);
                //ls.remove("three");
            }
        }

        System.out.println(ls.size());

    }

}

和输出

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at Test.main(Test.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at     sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.    java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

【问题讨论】:

标签: java list


【解决方案1】:

您不能在迭代列表时修改它。迭代器可能(也可能不会)失败,具体取决于实现。因此,删除列表中的某些元素可能会起作用,而其他元素可能不会。规避此问题的保存方法是使用迭代器 remove 方法,或使用 CopyOnWriteArrayList 或任何其他支持此类修改的集合。

【讨论】:

    猜你喜欢
    • 2015-05-27
    • 1970-01-01
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    相关资源
    最近更新 更多