HashMap を反復処理する [重複]
質問
内の項目を反復する最良の方法は何ですか? HashMap
?
解決
を繰り返します entrySet()
そのようです:
public static void printMap(Map mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}
について詳しく読む Map
.
他のヒント
キーだけに興味がある場合は、次の手順を繰り返すことができます。 keySet()
地図の:
Map<String, Object> map = ...;
for (String key : map.keySet()) {
// ...
}
値のみが必要な場合は、次を使用します。 values()
:
for (Object value : map.values()) {
// ...
}
最後に、キーと値の両方が必要な場合は、次を使用します。 entrySet()
:
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// ...
}
1 つの注意点:反復中に項目を削除したい場合は、Iterator を介して削除する必要があります (「 カリム79さんの答え)。ただし、項目値の変更は問題ありません (「 Map.Entry
).
参考文献より抜粋 Java でマップを反復処理する方法:
を反復するにはいくつかの方法があります Map
ジャワでは。最も一般的な方法を確認し、その長所と短所を確認してみましょう。Java のすべてのマップは Map インターフェイスを実装しているため、次のテクニックはどのマップ実装でも機能します (HashMap
, TreeMap
, LinkedHashMap
, Hashtable
, 、など)
方法 #1:For-Each ループを使用してエントリを反復します。
これは最も一般的な方法であり、ほとんどの場合に推奨されます。ループ内でマップ キーと値の両方が必要な場合に使用する必要があります。
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
For-Each ループは Java 5 で導入されたため、このメソッドは言語の新しいバージョンでのみ機能することに注意してください。また、For-Each ループはスローします NullPointerException
null のマップを反復処理しようとした場合は、反復する前に常に null 参照をチェックする必要があります。
方法 #2:For-Each ループを使用してキーまたは値を反復します。
マップのキーまたは値のみが必要な場合は、entrySet の代わりに keySet または値を反復処理できます。
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
// Iterating over keys only
for (Integer key : map.keySet()) {
System.out.println("Key = " + key);
}
// Iterating over values only
for (Integer value : map.values()) {
System.out.println("Value = " + value);
}
この方法では、パフォーマンスがわずかに向上します。 entrySet
反復が速くなり (約 10% 高速になり)、よりクリーンになります。
方法 #3:Iteratorを使用した反復処理。
ジェネリックスの使用:
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
ジェネリックなし:
Map map = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
Integer key = (Integer)entry.getKey();
Integer value = (Integer)entry.getValue();
System.out.println("Key = " + key + ", Value = " + value);
}
同じ手法を使用して反復処理することもできます keySet
または価値観。
この方法は冗長に見えるかもしれませんが、独自の利点があります。まず第一に、これは古いバージョンの Java でマップを反復処理する唯一の方法です。もう 1 つの重要な機能は、このメソッドが、呼び出しによって反復中にマップからエントリを削除できる唯一のメソッドであることです。 iterator.remove()
. 。For-Each 反復中にこれを実行しようとすると、次のように「予測できない結果」が得られます。 Javadoc.
パフォーマンスの観点から見ると、このメソッドは For-Each 反復と同等です。
方法 #4:キーを反復処理して値を検索します (非効率)。
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Integer key : map.keySet()) {
Integer value = map.get(key);
System.out.println("Key = " + key + ", Value = " + value);
}
これはメソッド 1 のよりクリーンな代替手段のように見えるかもしれませんが、キーによる値の取得に時間がかかる可能性があるため、実際にはかなり遅く非効率的です (さまざまな Map 実装でのこのメソッドは、メソッド 1 よりも 20% ~ 200% 遅くなります) )。FindBugs がインストールされている場合は、これを検出し、非効率な反復について警告します。この方法は避けるべきです。
結論:
マップのキーまたは値のみが必要な場合は、方法 #2 を使用します。Java の古いバージョン (5 未満) で行き詰まっている場合、または反復中にエントリを削除する予定がある場合は、方法 3 を使用する必要があります。それ以外の場合は、方法 #1 を使用してください。
for (Map.Entry<String, String> item : hashMap.entrySet()) {
String key = item.getKey();
String value = item.getValue();
}
内のエントリを反復処理できます。 Map
いくつかの方法で。次のように各キーと値を取得します。
Map<?,?> map = new HashMap<Object, Object>();
for(Entry<?, ?> e: map.entrySet()){
System.out.println("Key " + e.getKey());
System.out.println("Value " + e.getValue());
}
または、次のようにキーのリストを取得できます。
Collection<?> keys = map.keySet();
for(Object key: keys){
System.out.println("Key " + key);
System.out.println("Value " + map.get(key));
}
キーにはこだわらず、すべての値を取得したいだけの場合は、以下を使用できます。
Collection<?> values = map.values();
よりスマートに:
for (String key : hashMap.keySet()) {
System.out.println("Key: " + key + ", Value: " + map.get(key));
}
場合によります。すべてのエントリのキーと値の両方が必要になることがわかっている場合は、次の手順を実行します。 entrySet
. 。値だけが必要な場合は、 values()
方法。キーだけが必要な場合は、次を使用します keyset()
.
悪い習慣は、すべてのキーを反復処理し、ループ内で常に次のことを行うことです。 map.get(key)
値を取得します。そうする場合は、私が書いた最初のオプションが最適です。