集合:ConcurrentModificationException

时间:2013-08-31 22:53:35

标签: java

为什么我在以下代码中获得此ConcurrentModificationException

public static ArrayList<ArrayList<String>> buildPath(String s, String e, HashMap<String, ArrayList<String>> visited) {
    ArrayList<ArrayList<String>> ret = new ArrayList<ArrayList<String>>();
    ArrayList<ArrayList<String>> temp = new ArrayList<ArrayList<String>>();
    ArrayList<String> tmp = new ArrayList<String>();
    tmp.add(e);
    ret.add(tmp);
    boolean needStop = false;
    while (true) {
        for (ArrayList<String> al : ret) { //concurrent exception
            ArrayList<String> pre_words = visited.get(al.get(al.size() - 1));
            for (String pre_word : pre_words) {
                if (pre_word.compareTo(s) == 0) {
                    needStop = true;
                }
                if (needStop && pre_word.compareTo(s) != 0) {
                    continue;
                }
                ArrayList<String> toadd = new ArrayList<String>(al);
                toadd.add(pre_word);
                temp.add(toadd);

            }
        }
        ret = temp;
        if (needStop) {
            for (ArrayList<String> l : ret) {
                Collections.reverse(l);
            }
            return ret;
        }
    }
}

如果我进行以下更改,程序将正确运行:

自:

for(ArrayList<String> al : ret) {

为:

for(int i =0; i <ret.size() ; i++) {
    ArrayList<String> al = ret.get(i);

2 个答案:

答案 0 :(得分:1)

使用迭代器迭代它时,您将向列表中添加元素。这是导致此异常的原因。

非并发集合的迭代器是快速失败的:只要他们注意到在迭代期间修改了集合,就会抛出这样的异常。

答案 1 :(得分:1)

在循环时修改ConcurrentModificationException时会出现Collection,这是因为不支持此行为。

您的循环已超过ret

for(ArrayList<String> al : ret)

您修改tmp

temp.add(toadd);

然后,您将tmp分配给ret

ret= temp;

下次循环(大循环while(true))时,修改Collection即可获得ConcurrentModificationException

手动循环时没有得到的原因

for(int i =0; i <ret.size() ; i++)

是因为您没有使用在增强型foreach循环中隐式使用的Iterator。如果您不使用Iterator,则无法检查您的狡猾代码......