このようなコードを書きたい-
for (Map.Entry<Long, Integer> e : map.entrySet()){
map.remove(k);
map.put(x, value);
}
しかし、私はJava.util.ConcurrentModificationException
Iterator
も使用しようとしましたが、同じException
を取得しました
なぜそれがConcurrentModificationException
を引き起こしたのか説明
_map.remove(k);
map.put(x, value);
_
for-各ループは、entrySet
のmap
のイテレータも内部的に作成します。マップを反復処理しているときに、値をマップに再度配置することでマップの構造を変更しました(map.put(x,value)
)。これにより、このConcurrentModificationException
が発生します。
それは ドキュメント -でさえよく説明されています
このクラスのすべての「コレクションビューメソッド」によって返されるイテレータはフェイルファストです。イテレータが作成された後、イテレータ自体のremoveメソッド以外の方法でマップが構造的に変更された場合、イテレータはConcurrentModificationExceptionをスローします。 。したがって、同時変更に直面した場合、イテレータは、将来の不確定な時間に任意の非決定論的な動作のリスクを冒すのではなく、迅速かつクリーンに失敗します。
これを解決する方法-
反復中にこのマップの構造の変更を変更する必要があります。一時的なマップを保持し、反復が完了したらこれをメインマップに追加するなど、後でこの値を挿入できます。
_Map<Long, Integer> tempMap = new HashMap<>();
for (Map.Entry<Long, Integer> e : map.entrySet()){
map.remove(k);
tempMap.put(x, value);
}
map.putAll(tempMap);
_
マップから要素を削除するためのサンプルコードスニペットを以下に示します。
for(Iterator<Map.Entry<Long, Integer>> it = map.entrySet().iterator();it.next();)
{
Map.Entry<String, String> entry = it.next();
if(//some logic)
it.remove();
}
コードに多くの追加と削除が含まれる場合は、ConcurrentHashMapを使用することをお勧めします。 ConcurrentHashMap
コピーを繰り返し処理すると、問題なく追加/削除できます。
for (Map.Entry<Long, Integer> e : new LinkedHashMap<Long, Integer>(map).entrySet()){
map.remove(k);
map.put(x, value);
}
コピーはコピーコンストラクターを介してインラインで作成されるため、これ以上のコード行はありません。 LinkedHashMap
は、反復順序を維持するために選択されました(それが重要な場合)。
コピーコンストラクターを使用して、マップのコピーを作成する必要があります。ここで、1を繰り返し、2番目のマップを変更します。あまり意味がないので、新たに付加価値を繰り返す必要はないと思います。
コピーを作成することでタスクを実行できます。これは、両方のキーが同じままであるためです。
編集:
新しく追加された要素をハッシュマップに繰り返すのは良い考えではないと思います。 Iteratorによって提供されるAPIを確認すると、removeメソッドのみが見つかり、addメソッドは含まれていません。これには理由があり、javadocでこれを確認できます。ここで、新しく追加された要素を反復する方法について説明します。
HashMap
のコピーを作成します。したがって、一方を繰り返し、もう一方をMap
に変更します。Map
の要素の追加と削除の両方であるため、これにはListIterator
を使用したいと思います[これは通常のIterator
とは異なります]。keyset
を取得し、ArrayList(Collection<? extends E> c)
を使用してリストに変換します。ListIterator
からList
を取得し、ListIterator
とMap2の要素を追加および削除します[追加する必要があることを忘れないでください。ListIterator
とMap2の両方で削除してください]。あなたはそれをすることができないので。
簡単な解決策は、必要な値を配置し、最後にポインターを元のマップに切り替える別の一時マップを使用することです(つまり、Map = newMap)