内のアイテムを反復処理するための最良の方法は何HashMap
ですか?
7 に答える
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
)。
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
。
リファレンスから抽出Javaでマップを反復処理する方法:
Map
Javaで反復処理する方法はいくつかあります。最も一般的な方法を調べて、それらの長所と短所を確認しましょう。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ループはJava5で導入されたため、このメソッドは新しいバージョンの言語でのみ機能することに注意してください。また、nullのマップを反復処理しようとすると、For-Eachループがスローさ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:イテレータを使用して反復します。
ジェネリックの使用:
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のよりクリーンな代替手段のように見えるかもしれませんが、実際には、キーによる値の取得に時間がかかる可能性があるため、かなり遅く非効率的です(さまざまなマップ実装でのこのメソッドは、メソッド#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)
値を取得することです。あなたがそれをしているなら、私が書いた最初のオプションはあなたのためです。