あなたのストリームのコールは(論理的)と同じことをやっている:
for (K k : someMap.keySet()) {
if (!someList.contains(k)) {
someMap.remove(k);
}
}
これを実行する場合、あなたはそれがあなたと同じ時間にマップを変更しているので、それは、ConcurrentModificationException
を投げるでしょうそれを反復しています。あなたはdocsを見ている場合は、以下のことに気づくでしょう:
(注)この例外は常にオブジェクトが同時に別のスレッドによって変更されたことを示すものではありません。 1つのスレッドがオブジェクトの契約に違反する一連のメソッド呼び出しを発行すると、オブジェクトはこの例外をスローする可能性があります。たとえば、スレッドがフェイル・ファースト・イテレータを使用してコレクションを反復している間に、スレッドがコレクションを直接変更した場合、イテレータはこの例外をスローします。
これはあなたがやっていることですが、使用しているマップ実装にはフェイル・ファースト・イテレーターが含まれているため、この例外がスローされています。
一つの可能な選択肢は、直接イテレータを使用してアイテムを削除することです:
for (Iterator<K> ks = someMap.keySet().iterator(); ks.hasNext();) {
K next = ks.next();
if (!someList.contains(k)) {
ks.remove();
}
}
これは最善の答えだと思いますが、編集して@Eranが述べた解決策を追加することができます。それは、将来同じ問題を抱える人にとっては100%満足するでしょう。 – jaskmar
@MariuszJaskółka、Eranの回答もここにあり、他の人も同様にそれを見る可能性が高いです。それは正しいと私はそれをupvoted。私は彼のソリューションへの参照を追加することができます。 –