private int checkLevel(String bigWord, Collection<String> dict, MinMax minMax)
{
/*value initialised to losing*/
int value = 0;
if (minMax == MinMax.MIN) value = 1;
else value = -1;
boolean go = true;
Iterator<String> iter = dict.iterator();
while(iter.hasNext())
{
String str = iter.next();
Collection<Integer> inds = naiveStringSearch(bigWord, str);
if(inds.isEmpty())
{
iter.remove();
}
for (Integer i : inds)
{
MinMax passin = minMax.MIN;
if (minMax == MinMax.MIN) passin = minMax.MAX;
int value2 = checkLevel(removeWord(bigWord, str, i), dict, passin);
if (value2 == -1 && minMax == minMax.MIN)
{
value = -1;
go = false;
}
if (value2 == 1 && minMax == minMax.MAX)
{
value = 1;
go = false;
}
}
if (go == false) break;
}
return value;
}
错误:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:810)
at java.util.HashMap$KeyIterator.next(HashMap.java:845)
at aStringGame.Main.checkLevel(Main.java:67)
at aStringGame.Main.test(Main.java:117)
at aStringGame.Main.main(Main.java:137)
这里有什么问题?
答案 0 :(得分:5)
某处正在修改dict
。我怀疑它可能会在这个电话中发生:
int value2 = checkLevel(removeWord(bigWord, str, i), dict, passin);
^^^^
编辑基本上,对checkLevel()
的递归调用会通过另一个迭代器修改dict
。这使得外部迭代器的快速失败行为成为可能。
答案 1 :(得分:5)
当您使用迭代器迭代集合时,无法修改集合。
您尝试调用 iter.remove()会破坏此规则(也可能是 removeWord 方法)。
您 CAN 在迭代 IF 时使用ListIterator进行迭代来修改列表。
您可以将Set转换为List并使用List迭代器:
List<String> tempList = new ArrayList<String>(dict);
ListIterator li = tempList.listIterator();
另一种选择是在迭代时跟踪要删除的元素。
例如,您可以将它们放在一个Set中。
然后你可以在循环后调用 dict.removeAll()。
示例:
Set<String> removeSet = new HashSet<String>();
for (String s : dict) {
if (shouldRemove(s)) {
removeSet.add(s);
}
}
dict.removeAll(removeSet);
答案 2 :(得分:1)
使用for each
循环时,不允许修改循环内迭代的Collection
。如果您需要修改它,请使用经典的for
循环
答案 3 :(得分:1)
这是所有Collections类中常见的问题。例如,TreeSet中的条目使用failfast方法。
此类的迭代器方法返回的迭代器是快速失败的: 如果在创建迭代器后的任何时间修改了该集,则 除了通过迭代器自己的remove方法之外的任何方式,迭代器 将抛出ConcurrentModificationException。因此,面对 并发修改,迭代器快速干净地失败, 而不是冒着任意的,非确定性的行为冒险 未来不确定的时间。
http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html