私はこのようなコードを書きたい -
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);
entrySet
for-each ループも内部的にofのイテレータを作成します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 (Map.Entry<Long, Integer> e : new LinkedHashMap<Long, Integer>(map).entrySet()){
map.remove(k);
map.put(x, value);
}
コピーはコピー コンストラクターを介してインラインで作成されるため、これ以上のコード行は必要ありません。LinkedHashMap
反復順序を維持するために選択されました(それが重要な場合)。
マップから要素を削除するためのサンプル コード スニペットを以下に示します。
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 を使用することをお勧めします。コンカレントハッシュマップ
コピー コンストラクターを使用してマップのコピーを作成する必要があります。1 を繰り返し、2 番目のマップを変更します。あまり意味がないので、新しく追加された価値を繰り返す必要はないと思います。
コピーを作成することでタスクを達成できます。これは、キーが両方で同じままであるためです。
編集:
新しく追加された要素をハッシュマップに反復するのは良い考えだとは思いません。Iterator が提供する API を確認すると、remove メソッドのみが見つかり、そこには add メソッドはありません。これには理由があり、これについては javadoc を確認できます。ここで、新しく追加された要素を反復する方法について説明します。
HashMap
。したがって、一方を繰り返し、もう一方を変更しMap
ます。Map
に使用したいと思いますListIterator
[これは通常とは異なりますIterator
]。keyset
Map1の を取得し、を使用してリストに変換しArrayList(Collection<? extends E> c)
ます。ListIterator
し、Map2 と同様に要素を追加、削除します [Map2と Map2 の両方で追加、削除する必要があることを思い出してください]。List
ListIterator
ListIterator
それはできないからです。
簡単な解決策は、必要な値を配置する別の一時マップを使用し、最終的に元のポインターにポインターを切り替えることです (つまり、 Map = newMap )
次のようにマップをたどってみてください
while (tree_map.size() > 0){
// if k is key
if (tree_map.containsKey()){
tree_map.remove(k);
}
tree_map.put(x, value);
break;
// can go through the for loop or other code as per requirements
}