为什么我在以下代码中获得此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);
答案 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
,则无法检查您的狡猾代码......