0

文字列のセットをパラメーターとして取り、セットから偶数長の文字列をすべて削除するメソッド removeEvenLength を記述します。

私の解決策:

public static void removeEvenLength(Set<String> set) {
    for(String word : set) {
        if(word.length() % 2 == 0) {
            set.remove(word);
        }
    }
}

入力: [foo, buzz, bar, fork, bort, spoon, !, dude]

出力:

ConcurrentModificationException on line 2:
java.util.ConcurrentModificationException
    at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1115)
    at java.util.TreeMap$KeyIterator.next(TreeMap.java:1169)
    at removeEvenLength (Line 2)

を作成することで解決できIteratorます。しかし、上記のコードが機能しない理由を知りたいですか?

編集:

イテレータも機能しません:

public static void removeEvenLength(Set<String> set) {
    Iterator<String> i = set.iterator();
    while(i.hasNext()) {
        String word = i.next();
        if(word.length() % 2 == 0) {
            set.remove(word);
        }
    }
}

同じエラー。

4

2 に答える 2

5

この反復では、iteratorオブジェクトが暗黙的に作成されます。持っているiterator場合は、イテレータからコレクションを変更できます。この場合、オブジェクトを直接削除しているため、この例外がスローされます。

イテレータを作成し、イテレータでオブジェクトを削除します:

iterator.remove(); // removes current element
于 2013-02-05T21:54:32.663 に答える
2

なぜ発生するのかを理解するには、フェイルファスト反復ConcurrentModificationExceptionの概念を理解する必要があります。スレッドがコレクションを繰り返し処理していて、その繰り返しの進行中にコレクションが変更されていることに気付いた場合、反復子はコードの後半で整合性の問題を「おそらく」引き起こすのではなく、例外をスローします。

もちろん、すべての反復子がこのアプローチに従うわけではなく、Java を使用するIteratorと、ほとんどの場合、変更時に反復が失敗しないことが保証されます。

イテレータを使用して要素を削除するには、次のコードを使用します

Iterator<String> iter = list.iterator();
    while(iter.hasNext()) {
        String obj = iter.next();
        if(<removal_condition_here>) {
            iter.remove();
        }
    }
于 2013-02-05T21:56:38.660 に答える