2017-03-29 30 views
0

のJava - HashMapの反復 - のような私はHashMapを反復処理したい例外

 for (Map.Entry<Integer, Integer> entry : map.entrySet()) { 
      map.replace(entry.getKey(), entry.getValue()-1); 
      if (entry.getValue() == 0) { 
       map.remove(entry.getKey(), 0); 
      } 
     } 

は、これは例外で終わる:java.util.ConcurrentModificationExceptionが

任意のソリューションを?

種類は、あなたがそれを反復しているとして、あなたは、マップから項目を削除している

+1

代わりにイテレータを使用してください。 – Zircon

+4

"セット上の反復処理中にマップが変更された場合(イテレータ自身の' remove'オペレーションまたはイテレータによって返されたマップエントリ上の 'setValue'オペレーションを通して)、反復の結果は未定義です" http://docs.oracle.com/javase/8/docs/api/java/util/Map.html#entrySet--ここで、「未定義」はCMEをスローすることを意味します。 –

答えて

1
Iterator<Map.Entry<Integer, Integer>> entryItr = map.entrySet().iterator(); 
while (entryItr.hasNext()) { 
    Map.Entry<Integer, Integer> entry = entryItr.next(); 
    if (entry.getValue() > 1) { 
    entry.setValue(entry.getValue() - 1); 
    } else { 
    entryItr.remove(); 
    } 
} 
0

について。これが例外の原因です。

マップが3つのアイテムを含み、最初の繰り返しで最初のアイテムを削除した場合、次のアイテムが2番目または3番目のアイテムである必要があります。削除されたアイテムがまだそこに残っているかのように反復処理を続行する必要がありますか?そしてもしそうなら、どうですか?

マップの各要素を安全に通過するイテレータをマップ上で使用することで回避できます。

0

あなたはそれがスローされます、それ以外の場合は、Iteratorを使用せずに、既存のSetから要素を削除することはできませんConcurrentModificationException

ので、newMapオブジェクトif(value-1 !=0)に場所値は下記のように:

 Map<Integer, Integer> map = new HashMap<>(); 
     Map<Integer, Integer> newMap = new HashMap<>(); 
     Iterator<Integer> iterator =map.keySet().iterator(); 
     while(iterator.hasNext()) { 
      int key = iterator.next(); 
      int value = map.get(key); 
      if(value-1 !=0) { 
       newMap.put(key, value-1); 
      } 
     } 
+0

'Iterator.remove()'を使ってその場で行うことができます。どうして? –

+0

OPは既存のキーの値を変更したい – developer

+0

はい、および?削除されていないエントリには 'Entry.setValue'を、エントリには' Iterator.remove'を使用できます。 –