コレクションを反復処理し、ループ内のオブジェクトを削除するときに ConcurrentModificationException を回避する 質問する

コレクションを反復処理し、ループ内のオブジェクトを削除するときに ConcurrentModificationException を回避する 質問する

私たちは皆、次の理由により、次のことができないことを知っていますConcurrentModificationException:

for (Object i : l) {
    if (condition(i)) {
        l.remove(i);
    }
}

しかし、どうやらこれは時々は機能しますが、常に機能するわけではありません。具体的なコードは次のとおりです。

public static void main(String[] args) {
    Collection<Integer> l = new ArrayList<>();

    for (int i = 0; i < 10; ++i) {
        l.add(4);
        l.add(5);
        l.add(6);
    }

    for (int i : l) {
        if (i == 5) {
            l.remove(i);
        }
    }

    System.out.println(l);
}

当然、その結果は次のようになります。

Exception in thread "main" java.util.ConcurrentModificationException

複数のスレッドがそれを実行していないにもかかわらず。とにかく。

この問題の最善の解決策は何でしょうか? この例外をスローせずにループ内のコレクションからアイテムを削除するにはどうすればよいでしょうか?

Collectionまた、ここでは ではなく任意の を使用しているArrayListため、 に頼ることはできませんget

ベストアンサー1

Iterator.remove()安全であれば、次のように使用できます。

List<String> list = new ArrayList<>();

// This is a clever way to create the iterator and call iterator.hasNext() like
// you would do in a while-loop. It would be the same as doing:
//     Iterator<String> iterator = list.iterator();
//     while (iterator.hasNext()) {
for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
    String string = iterator.next();
    if (string.isEmpty()) {
        // Remove the current element from the iterator and the list.
        iterator.remove();
    }
}

ご了承くださいIterator.remove()反復処理中にコレクションを変更する唯一の安全な方法です。反復処理の進行中に基になるコレクションが他の方法で変更された場合、動作は未指定になります。

ソース:docs.oracle > コレクション インタフェース


同様に、アイテムを追加しListIteratorたい場合は、ListIterator#add、使用できるのと同じ理由でIterator#remove 、それを許可するように設計されています。


あなたの場合、リストから削除しようとしましたが、その内容を反復しながら削除しようとする場合も同じ制限が適用されputますMap

おすすめ記事