可能な重複:
'Map'の各エントリを効率的に反復する方法
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();
// ...
}
注意点:反復の途中でアイテムを削除したい場合は、イテレータを使って削除する必要があります( karim79の回答 を参照)。ただし、項目値を変更しても問題ありません( Map.Entry
を参照)。
参照から抽出されたJavaでマップを反復する方法:
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ループでは、nullのマップを反復しようとするとNullPointerException
がスローされるため、反復する前に必ず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のよりクリーンな代替方法のように見えるかもしれませんが、実際にはキーによって値を取得するのは時間がかかるかもしれないので非常に遅くそして非効率的です。 ) 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)
を実行することです。あなたがそれをやっているなら、それから私が書いた最初のオプションはあなたのためです。