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);
                                                     ^^^^

edit基本的に、 への再帰呼び出しが別のイテレータを介してcheckLevel()変更されます。これにより、外側の反復子のフェイルファスト動作が開始されます。dict

于 2012-12-03T22:11:53.787 に答える
4

Iterator を使用してコレクションを反復処理している間は、コレクションを変更することはできません。

iter.remove()を呼び出そうとすると、このルールが破られます ( removeWordメソッドもそうなる可能性があります)。

ListIteratorを使用して反復する場合、反復中にListを変更できます。

Set を List に変換し、List イテレータを使用できます。

List<String> tempList = new ArrayList<String>(dict);
ListIterator li = tempList.listIterator();

別のオプションは、反復中に削除する要素を追跡することです。

たとえば、それらをセットに配置できます。

その後、ループの後に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

これは、すべての Collections クラスで一般的に発生します。たとえば、TreeSet のエントリはフェイルファスト メソッドを使用します。

このクラスの iterator メソッドによって返される反復子は、フェイルファストです。反復子の作成後に、反復子自体の remove メソッド以外の方法でセットが変更されると、反復子は ConcurrentModificationException をスローします。したがって、同時変更に直面した場合、反復子は、将来の不確定な時点で恣意的で非決定論的な動作を危険にさらすのではなく、迅速かつ明確に失敗します。

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

于 2012-12-03T22:13:28.787 に答える
1

ループを使用する場合、for eachループ内で繰り返しているものを変更することはできませんCollection。変更する必要がある場合は、従来のforループを使用してください

于 2012-12-03T22:13:02.217 に答える