Итерация через HashMap [дубликат]

Возможные Дубликаты:
как эффективно перебирать каждую запись в "карте"?

каков наилучший способ перебора элементов в HashMap?

7 ответов


перебора 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:

существует несколько способов итерации над Map в Java. Давайте рассмотрим наиболее распространенные методы и рассмотрим их преимущества и недостатки. Поскольку все карты в Java реализуют интерфейс карты, следующие методы будут работать для любой реализации Карты (HashMap, TreeMap, LinkedHashMap, Hashtable, etc.)

Способ #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, поэтому этот метод работает только в более новых версиях языка. Также A For-каждый цикл будет бросать NullPointerException если вы пытаетесь выполнить итерацию по карте, которая равна null, поэтому перед итерацией вы всегда должны проверять значение null ссылки на литературу.

Способ #2: итерация по ключам или значениям с использованием цикла For-Each.

Если вам нужны только ключи или значения из карты, вы можете перебирать набор ключей или значения вместо entrySet.

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. Другая важная особенность заключается в том, что это единственный метод, который позволяет удалять записи с карты во время итерации, вызывая iterator.remove(). Если вы попытаетесь сделать это во время За-каждую итерацию вы получите "непредсказуемые результаты" в соответствии с Javadoc.

С точки зрения производительности этот метод равен для каждой итерации.

Способ #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, но на практике это довольно медленно и неэффективно, поскольку получение значений ключом может занять много времени (это метод в различных реализациях карты на 20% -200% медленнее, чем метод #1). Если у вас установлены FindBugs, он обнаружит это и предупредит вас о неэффективной итерации. Этого метода следует избегать.

вывод:

Если вам нужны только ключи или значения с карты, используйте метод #2. Если вы застряли с более старой версией Java (менее 5) или планируете удалить записи во время итерации, вы должны использовать метод #3. В противном случае используйте метод #1.


for (Map.Entry<String, String> item : params.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) чтобы получить значение. Если вы это делаете, то первый вариант, который я написал, для вас.