1. ホーム
  2. java

[解決済み] コレクションを反復処理し、ループ内でオブジェクトを削除する際に ConcurrentModificationException を回避する。

2022-03-15 05:01:51

質問

のため、以下のことができないことは周知のとおりです。 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 .

解決方法は?

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 の内容を繰り返しながら