HashMapを反復処理します

2009年07月01日に質問されました。  ·  閲覧回数 3.9M回  ·  ソース

burntsugar picture
2009年07月01日

HashMap内のアイテムを反復処理するための最良の方法は何ですか?

回答

harto picture
2009年07月01日
4886

キーのみに関心がある場合は、マップの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 )。

karim79 picture
2009年07月01日
3325

次のように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についてもっと読む。

arvind picture
2011年12月08日
848

参照から抽出Javaでマップを反復処理する方法

JavaでMapを反復処理する方法はいくつかあります。 最も一般的な方法を調べて、それらの長所と短所を確認しましょう。 JavaのすべてのマップはMapインターフェースを実装しているため、次の手法はどのマップ実装でも機能します( HashMapTreeMapLinkedHashMapHashtableなど)。 )

方法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 :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のよりクリーンな代替手段のように見えるかもしれませんが、実際には、キーによる値の取得に時間がかかる可能性があるため、かなり遅く非効率的です(異なるマップ実装でのこのメソッドはメソッド#1よりも20%〜200%遅くなります)。 FindBugsがインストールされている場合は、これを検出し、非効率的な反復について警告します。 この方法は避けてください。

結論:

マップのキーまたは値のみが必要な場合は、方法#2を使用します。 古いバージョンのJava(5未満)で立ち往生している場合、または反復中にエントリを削除することを計画している場合は、方法#3を使用する必要があります。 それ以外の場合は、方法1を使用します。

gabor picture
2011年07月23日
172
for (Map.Entry<String, String> item : hashMap.entrySet()) {
    String key = item.getKey();
    String value = item.getValue();
}
codethulhu picture
2009年07月01日
103

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();
jkarretero picture
2010年08月11日
72

よりスマート:

for (String key : hashMap.keySet()) {
    System.out.println("Key: " + key + ", Value: " + map.get(key));
}
Gary Kephart picture
2009年07月01日
51

依存します。 すべてのエントリのキーと値の両方が必要になることがわかっている場合は、 entrySet 。 値だけが必要な場合は、 values()メソッドがあります。 キーだけが必要な場合は、 keyset()ます。

悪い習慣は、すべてのキーを反復処理してから、ループ内で常にmap.get(key)を実行して値を取得することです。 あなたがそれをしているなら、私が書いた最初のオプションはあなたのためです。