4
    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)

这里有什么问题?

4

4 回答 4

5

某处正在修改dict。我怀疑它可能发生在这个调用中:

int value2 = checkLevel(removeWord(bigWord, str, i), dict, passin);
                                                     ^^^^

编辑基本上,发生的事情是递归调用通过另一个迭代器进行checkLevel()修改。这使得外部迭代器的快速失败行为开始发挥作用。dict

于 2012-12-03T22:11:53.787 回答
4

当您使用迭代器对其进行迭代时,您无法修改集合。

您尝试调用iter.remove()违反了此规则(您的removeWord方法也可能)。

如果您使用ListIterator进行迭代,则可以在迭代时修改 List

您可以将 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);
于 2012-12-03T22:11:56.140 回答
1

使用for each循环时,您不允许修改Collection您在循环内迭代的内容。如果需要修改,请使用经典for循环

于 2012-12-03T22:13:02.217 回答
1

这是所有 Collections 类中常见的情况。例如,TreeSet 中的条目使用 failfast 方法。

此类的迭代器方法返回的迭代器是快速失败的:如果在创建迭代器后的任何时间修改集合,除了通过迭代器自己的 remove 方法之外,迭代器将抛出 ConcurrentModificationException。因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。

http://docs.oracle.com/javase/6/docs/api/java/util/TreeSet.html

于 2012-12-03T22:13:28.787 回答