Итерация через HashMap
Возможный дубликат:
Как эффективно перебрать каждую запись в "Карте"?
Какой лучший способ перебрать элементы в HashMap
?
Ответы
Ответ 1
entrySet()
по 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
.
Ответ 2
Если вас интересуют только ключи, вы можете перебрать 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 answer). Тем не менее, изменение значений элемента в порядке (см. Map.Entry
).
Ответ 3
Извлечен из ссылки Итерация по карте в 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-Every был введен в Java 5, поэтому этот метод работает только в более новых версиях языка. Также цикл For-Each будет бросать NullPointerException
, если вы попытаетесь выполнить итерацию по карте, которая равна 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());
}
Без Generics:
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.
С точки зрения производительности этот метод равен Итерации 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 на 20% -200% медленнее, чем метод № 1). Если у вас установлен FindBugs, он обнаружит это и предупредит вас о неэффективной итерации. Этот метод следует избегать.
Вывод:
Если вам нужны только ключи или значения с карты, используйте метод # 2. Если вы застряли со старой версией Java (менее 5) или планируете удалять записи во время итерации, вы должны использовать метод # 3. В противном случае используйте метод # 1.
Ответ 4
for (Map.Entry<String, String> item : hashMap.entrySet()) {
String key = item.getKey();
String value = item.getValue();
}
Ответ 5
Вы можете перебирать записи на 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();
Ответ 6
Smarter:
for (String key : hashMap.keySet()) {
System.out.println("Key: " + key + ", Value: " + map.get(key));
}
Ответ 7
Зависит. Если вы знаете, что вам понадобится как ключ, так и значение каждой записи, перейдите к entrySet
. Если вам нужны только значения, то существует метод values()
. И если вам просто нужны ключи, используйте keyset()
.
Плохая практика заключалась бы в том, чтобы перебирать все ключи, а затем в цикле всегда делать map.get(key)
для получения значения. Если вы это делаете, то первый вариант, который я написал, для вас.