39 Вопрос: Как эффективно перебрать каждую запись на карте Java?

вопрос создан в Sun, Jan 6, 2019 12:00 AM

Если у меня есть объект, реализующий интерфейс Map в Java, и я хочу перебирать каждую содержащуюся в нем пару, каков наиболее эффективный способ прохождения карты?

Будет ли порядок элементов зависеть от конкретной реализации карты, которую я имею для интерфейса?

    
2964
  1. В Java 8 используется лямбда-выражение: stackoverflow.com/a/25616206/1503859
    2015-07-25 18: 31: 49Z
  2. 2018-10-10 12: 45: 28Z
30 ответов                              30                         
Map<String, String> map = ...
for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + "/" + entry.getValue());
}
    
4635
2019-03-14 22: 20: 24Z
  1. Если вы сделаете это, он не будет работать, так как Entry является вложенным классом в Map. java.sun.com/javase/6/docs/апи /Java /Util /Map.html
    2010-03-22 13: 30: 04Z
  2. вы можете записать импорт как "import java.util.Map.Entry;" и это будет работать.
    2010-04-30 10: 34: 19Z
  3. @ Pureferret Единственная причина, по которой вы можете использовать итератор, - это необходимость вызывать его метод remove. Если это так, этот другой ответ покажет вам, как это сделать. В противном случае расширенный цикл, как показано в ответе выше, - это путь.
    2012-10-08 10: 34: 14Z
  4. Я считаю, что форма Map.Entry понятнее, чем импорт внутреннего класса в текущее пространство имен.
    2014-12-04 20: 31: 27Z
  5. Обратите внимание, что вы можете использовать map.values() или map.keySet(), если вы хотите просматривать только значения или ключи.
    2016-10-12 21: 03: 58Z

Чтобы суммировать другие ответы и объединить их с тем, что я знаю, я нашел 10 основных способов сделать это (см. ниже). Кроме того, я написал несколько тестов производительности (см. Результаты ниже). Например, если мы хотим найти сумму всех ключей и значений карты, мы можем написать:

  1. Использование итератора и Map.Entry

    long i = 0;
    Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry<Integer, Integer> pair = it.next();
        i += pair.getKey() + pair.getValue();
    }
    
  2. Использование foreach и Map.Entry

    long i = 0;
    for (Map.Entry<Integer, Integer> pair : map.entrySet()) {
        i += pair.getKey() + pair.getValue();
    }
    
  3. Использование forEach из Java 8

    final long[] i = {0};
    map.forEach((k, v) -> i[0] += k + v);
    
  4. Использование keySet и foreach

    long i = 0;
    for (Integer key : map.keySet()) {
        i += key + map.get(key);
    }
    
  5. Использование keySet и итератора

    long i = 0;
    Iterator<Integer> itr2 = map.keySet().iterator();
    while (itr2.hasNext()) {
        Integer key = itr2.next();
        i += key + map.get(key);
    }
    
  6. Использование for и Map.Entry

    long i = 0;
    for (Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); entries.hasNext(); ) {
        Map.Entry<Integer, Integer> entry = entries.next();
        i += entry.getKey() + entry.getValue();
    }
    
  7. Использование Java 8 Stream API

    final long[] i = {0};
    map.entrySet().stream().forEach(e -> i[0] += e.getKey() + e.getValue());
    
  8. Использование Java 8 Stream API параллельно

    final long[] i = {0};
    map.entrySet().stream().parallel().forEach(e -> i[0] += e.getKey() + e.getValue());
    
  9. Использование IterableMap из Apache Collections

    long i = 0;
    MapIterator<Integer, Integer> it = iterableMap.mapIterator();
    while (it.hasNext()) {
        i += it.next() + it.getValue();
    }
    
  10. Использование MutableMap коллекций Eclipse (CS)

    final long[] i = {0};
    mutableMap.forEachKeyValue((key, value) -> {
        i[0] += key + value;
    });
    

Тесты производительности (режим = Среднее время, система = 64-разрядная версия Windows 8.1, Intel i7-4790 3,60 ГГц, 16 ГБ)

  1. Для маленькой карты (100 элементов) лучше всего набрать 0,308

    Benchmark                          Mode  Cnt  Score    Error  Units
    test3_UsingForEachAndJava8         avgt  10   0.308 ±  0.021  µs/op
    test10_UsingEclipseMap             avgt  10   0.309 ±  0.009  µs/op
    test1_UsingWhileAndMapEntry        avgt  10   0.380 ±  0.014  µs/op
    test6_UsingForAndIterator          avgt  10   0.387 ±  0.016  µs/op
    test2_UsingForEachAndMapEntry      avgt  10   0.391 ±  0.023  µs/op
    test7_UsingJava8StreamApi          avgt  10   0.510 ±  0.014  µs/op
    test9_UsingApacheIterableMap       avgt  10   0.524 ±  0.008  µs/op
    test4_UsingKeySetAndForEach        avgt  10   0.816 ±  0.026  µs/op
    test5_UsingKeySetAndIterator       avgt  10   0.863 ±  0.025  µs/op
    test8_UsingJava8StreamApiParallel  avgt  10   5.552 ±  0.185  µs/op
    
  2. Для карты с 10000 элементов оценка 37.606 является лучшей

    Benchmark                           Mode   Cnt  Score      Error   Units
    test10_UsingEclipseMap              avgt   10    37.606 ±   0.790  µs/op
    test3_UsingForEachAndJava8          avgt   10    50.368 ±   0.887  µs/op
    test6_UsingForAndIterator           avgt   10    50.332 ±   0.507  µs/op
    test2_UsingForEachAndMapEntry       avgt   10    51.406 ±   1.032  µs/op
    test1_UsingWhileAndMapEntry         avgt   10    52.538 ±   2.431  µs/op
    test7_UsingJava8StreamApi           avgt   10    54.464 ±   0.712  µs/op
    test4_UsingKeySetAndForEach         avgt   10    79.016 ±  25.345  µs/op
    test5_UsingKeySetAndIterator        avgt   10    91.105 ±  10.220  µs/op
    test8_UsingJava8StreamApiParallel   avgt   10   112.511 ±   0.365  µs/op
    test9_UsingApacheIterableMap        avgt   10   125.714 ±   1.935  µs/op
    
  3. Для карты с 100000 элементов оценка 1184,767 - лучшая

    Benchmark                          Mode   Cnt  Score        Error    Units
    test1_UsingWhileAndMapEntry        avgt   10   1184.767 ±   332.968  µs/op
    test10_UsingEclipseMap             avgt   10   1191.735 ±   304.273  µs/op
    test2_UsingForEachAndMapEntry      avgt   10   1205.815 ±   366.043  µs/op
    test6_UsingForAndIterator          avgt   10   1206.873 ±   367.272  µs/op
    test8_UsingJava8StreamApiParallel  avgt   10   1485.895 ±   233.143  µs/op
    test5_UsingKeySetAndIterator       avgt   10   1540.281 ±   357.497  µs/op
    test4_UsingKeySetAndForEach        avgt   10   1593.342 ±   294.417  µs/op
    test3_UsingForEachAndJava8         avgt   10   1666.296 ±   126.443  µs/op
    test7_UsingJava8StreamApi          avgt   10   1706.676 ±   436.867  µs/op
    test9_UsingApacheIterableMap       avgt   10   3289.866 ±  1445.564  µs/op
    

Графики (тесты производительности в зависимости от размера карты)

 Введите описание изображения здесь

Таблица (тесты производительности в зависимости от размера карты)

          100     600      1100     1600     2100
test10    0.333    1.631    2.752    5.937    8.024
test3     0.309    1.971    4.147    8.147   10.473
test6     0.372    2.190    4.470    8.322   10.531
test1     0.405    2.237    4.616    8.645   10.707
test2     0.376    2.267    4.809    8.403   10.910
test7     0.473    2.448    5.668    9.790   12.125
test9     0.565    2.830    5.952   13.220   16.965
test4     0.808    5.012    8.813   13.939   17.407
test5     0.810    5.104    8.533   14.064   17.422
test8     5.173   12.499   17.351   24.671   30.403

Все тесты проводятся на GitHub .

    
982
2018-04-10 21: 44: 37Z
  1. @ Viacheslav: очень хороший ответ. Просто интересно, как Java8 apis мешает, в вашем тесте, захватывая лямбды ... (например, long sum = 0; map.forEach( /* accumulate in variable sum*/); захватывает длину sum, что может быть медленнее, чем, например, stream.mapToInt(/*whatever*/).sum. Конечно, вы не всегда можете избежать захвата состояния, но это может быть разумное дополнение к скамейке.
    2016-05-12 11: 53: 34Z
  2. Ваш 8 тест неверен. он обращается к одной и той же переменной из разных потоков без синхронизации. Перейдите на AtomicInteger для решения проблемы.
    2016-09-13 15: 20: 53Z
  3. @ ZhekaKozlov: посмотрите на невероятно большие значения ошибок. Учтите, что результат теста x±e предполагает, что существует результат в пределах интервала от x-e до x+e, так что самый быстрый результат (1184.767±332.968) находится в диапазоне от 852 до 1518, в то время как второй самый медленный (1706.676±436.867) проходит между 1270 и 2144, поэтому результаты еще значительно перекрываются Теперь посмотрим на самый медленный результат, 3289.866±1445.564, который подразумевает расхождение между 1844 и 4735, и вы знаете , что эти результаты теста не имеют смысла.
    2017-03-17 18: 28: 28Z
  4. А как насчет map.entrySet().stream().[parallel().]mapToInt(e -> e.getKey() + e.getValue()).sum();?
    2017-06-04 21: 45: 15Z
  5. А как насчет сравнения 3 основных реализаций: HashMap, LinkedHashMap и TreeMap?
    2017-11-07 23: 37: 57Z

В Java 8 вы можете делать это чисто и быстро, используя новые функции лямбда-выражений:

 Map<String,String> map = new HashMap<>();
 map.put("SomeKey", "SomeValue");
 map.forEach( (k,v) -> [do something with key and value] );

 // such as
 map.forEach( (k,v) -> System.out.println("Key: " + k + ": Value: " + v));

Тип k и v будет определен компилятором, и больше нет необходимости использовать Map.Entry.

Easy-Peasy!

    
260
2016-09-07 08: 33: 17Z
  1. В зависимости от того, что вы хотите сделать с картой, вы также можете использовать потоковый API для записей, возвращаемых map.entrySet().stream() docs.oracle.com/javase/8/docs/api/java/util/stream/Stream. HTML
    2014-06-28 12: 46: 14Z
  2. Это не сработает, если вы хотите ссылаться на неконечные переменные, объявленные вне вашего лямбда-выражения изнутри forEach () ...
    2017-04-20 20: 29: 31Z
  3. @ Chris Correct. Это не сработает, если вы попытаетесь использовать эффективно неконечные переменные извне лямбды.
    2017-04-21 21: 44: 16Z

Да, порядок зависит от конкретной реализации Map.

@ ScArcher2 имеет больше элегантный синтаксис Java 1.5 . В 1.4 я бы сделал что-то вроде этого:

Iterator entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
  Entry thisEntry = (Entry) entries.next();
  Object key = thisEntry.getKey();
  Object value = thisEntry.getValue();
  // ...
}
    
220
2018-02-06 22: 32: 29Z
  1. Предпочитаю цикл for, чем while .. for (Iterator records = myMap.entrySet (). iterator (); records.hasNext ();) {...} С этим синтаксисом область «записей» сводится только к циклу for.
    2009-10-20 13: 20: 05Z
  2. @ jpredham Вы правы, что использование конструкции for в качестве for (Entry e : myMap.entrySet) не позволит вам изменить коллекцию, но пример, как упомянул @HanuAthena, должен работать, поскольку он дает Вы Iterator по объему. (Если я что-то упустил ...)
    2012-01-10 15: 42: 29Z
  3. IntelliJ сообщает мне об ошибках Entry thisEntry = (Entry) entries.next();: не распознает Entry. Это псевдокод для чего-то еще?
    2015-01-10 00: 06: 57Z
  4. @ JohnK попробуйте импортировать java.util.Map.Entry.
    2015-01-14 02: 35: 45Z
  5. Это решение не будет работать, если у вас есть целочисленный ключ и ключ String.
    2017-01-21 08: 09: 19Z

Типичный код для итерации по карте:

Map<String,Thing> map = ...;
for (Map.Entry<String,Thing> entry : map.entrySet()) {
    String key = entry.getKey();
    Thing thing = entry.getValue();
    ...
}

HashMap является реализацией канонической карты и не дает гарантий (или хотя она не должна изменять порядок, если на ней не выполняется операция мутации). SortedMap будет возвращать записи на основе естественного порядка ключей или Comparator, если он предусмотрен. LinkedHashMap будет либо возвращать записи в порядке вставки или порядке доступа в зависимости от того, как он был построен. EnumMap возвращает записи в естественном порядке ключей.

(Обновление: я думаю, что это больше не соответствует действительности. ) Примечание. IdentityHashMap entrySet итератор в настоящее время имеет особую реализацию, которая возвращает один и тот же экземпляр Map.Entry для каждого элемента в entrySet! Однако каждый раз, когда обновляется новый итератор, Map.Entry обновляется.

    
120
2018-02-09 01: 11: 36Z
  1. EnumMap также имеет это своеобразное поведение наряду с IdentityHashMap
    2011-03-10 15: 41: 06Z
  2. "LinkedHashMap будет либо возвращать записи в [...] access-order [...]" ... так что вы обращаетесь к элементам в том порядке, в котором вы к ним обращаетесь ? Либо тавтологическое, либо что-то интересное, что может использовать отступление. ; -)
    2016-01-26 20: 41: 34Z
  3. @ jpaugh Только прямой доступ к счетчику LinkedHashMap. Те, кто до iterator, spliterator, entrySet и т. Д., Не изменяют порядок.
    2016-01-26 21: 24: 00Z
  4. 1. , хотя → , если ? 2. Последний параграфч может выиграть от чистки.
    2018-02-06 22: 36: 54Z

Пример использования итератора и обобщений:

Iterator<Map.Entry<String, String>> entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
  Map.Entry<String, String> entry = entries.next();
  String key = entry.getKey();
  String value = entry.getValue();
  // ...
}
    
106
2009-08-18 17: 34: 51Z
  1. Вы должны поместить Iterator в цикл for, чтобы ограничить его область.
    2012-02-17 20: 32: 02Z
  2. @ SteveKuo Что вы подразумеваете под "ограничить область действия"?
    2015-02-03 16: 13: 23Z
  3. @ StudioWorks for (Iterator<Map.Entry<K, V>> entries = myMap.entrySet().iterator(); entries.hasNext(); ) { Map.Entry<K, V> entry = entries.next(); }. Используя эту конструкцию, мы ограничиваем область действия (видимость переменной) entries циклом for.
    2015-03-13 16: 33: 37Z
  4. @ ComFreek О, понятно. Не знал, что это так важно.
    2015-03-13 16: 59: 35Z

Это вопрос из двух частей:

Как перебирать записи на карте - @ ScArcher2 ответил , что отлично . р>

Каков порядок итерации - если вы просто используете Map, то, строго говоря, нет никаких гарантий порядка . Таким образом, вы не должны полагаться на порядок, заданный любой реализацией. Однако SortedMap интерфейс расширяет Map и предоставляет именно то, что вы ищете - реализации всегда будут давать последовательный порядок сортировки.

NavigableMap - еще один полезное расширение - это SortedMap с дополнительными методами для поиска записей по их упорядоченной позиции в наборе ключей. Таким образом, потенциально это может устранить необходимость в итерации в первую очередь - вы можете найти конкретные entry, которые вы используете после использования higherEntry, lowerEntry, ceilingEntry или floorEntry или descendingMap. Метод entrySet() даже дает вам явный метод изменить порядок обхода .

    
91
2017-05-23 11: 47: 32Z

Существует несколько способов перебора карты.

Вот сравнение их характеристик для общего набора данных, хранящегося в карте, путем сохранения миллиона пар значений ключа в карте и повторения по карте.

1) Использование

for (Map.Entry<String,Integer> entry : testMap.entrySet()) {
    entry.getKey();
    entry.getValue();
}
для каждого цикла

keySet()

50 миллисекунд

2) Использование

for (String key : testMap.keySet()) {
    testMap.get(key);
}
для каждого цикла

entrySet()

76 миллисекунд

3) Использование

Iterator<Map.Entry<String,Integer>> itr1 = testMap.entrySet().iterator();
while(itr1.hasNext()) {
    Map.Entry<String,Integer> entry = itr1.next();
    entry.getKey();
    entry.getValue();
}
и итератора

keySet()

50 миллисекунд

4) Использование

Iterator itr2 = testMap.keySet().iterator();
while(itr2.hasNext()) {
    String key = itr2.next();
    testMap.get(key);
}
и итератора

this link

75 миллисекунд

Я ссылался на

for (String key: map.keySet()) {
   System.out.println(key + "/" + map.get(key));
}
. р>     

73
2015-07-18 15: 58: 26Z
  1. Очень хороший пример! Я предпочитаю использовать способ # 1.
    2016-01-15 04: 24: 37Z
  2. Время выполнения взято из статьи, в которой не используется Java Microbenchmarking Harness. Поэтому времена ненадежны, так как, например, код мог быть полностью оптимизирован компилятором JIT.
    2019-01-14 13: 44: 28Z

Правильный способ сделать это - использовать принятый ответ, так как он наиболее эффективен. Я считаю, что следующий код выглядит немного чище.

O(1) = 2*O(1)     
52
2011-10-17 00: 16: 44Z
  1. Это не лучший подход, гораздо эффективнее использовать entrySet (). Findbugs помечает этот код (см. findbugs.sourceforge.net/… )
    2009-11-06 20: 46: 26Z
  2. @ ДжеффОлсон, не очень. поиск по карте равен O (1), поэтому оба цикла ведут себя одинаково. по общему признанию, это будет немного медленнее в микро тесте, но я иногда делаю это также, потому что я ненавижу писать аргументы типа снова и снова Кроме того, это, скорее всего, никогда не станет вашим узким местом в производительности, поэтому сделайте это, если это сделает код более читабельным.
    2012-10-08 13: 25: 12Z
  3. более подробно: 2 - это в значительной степени определение большой O-нотации. вы правы в том, что он работает немного медленнее, но с точки зрения сложности они одинаковы.
    2012-10-08 23: 26: 27Z
  4. при столкновении или нет, я имел в виду, что это не имеет значения, если вы столкнулись несколько раз, очевидно, это другая история, если у вас есть только столкновения. так что ты довольно мелок, но да, то, что ты говоришь, правда.
    2012-12-23 16: 17: 11Z
  5. @ Джефф Олсон: комментарии о том, что сложность «Big O» не меняется, когда присутствует только постоянный коэффициент, являются правильными. Тем не менее, для меня важно, займет ли операция один час или два часа. Что еще более важно, следует подчеркнуть, что коэффициент не entrySet(), так как итерация по keySet() вообще не несет поиска; это просто линейный обход всех записей. Напротив, итерация по Map и выполнение поиска по ключу приводит к одному поиску по ключу, поэтому мы говорим о нулевых поисках по сравнению с n поисками здесь, n , являющийся размером 2. Таким образом, коэффициент находится далеко за пределами map.keySet()
    2016-11-09 12: 22: 02Z

К вашему сведению, вы также можете использовать map.values() и

final MutableBag<String> result = Bags.mutable.empty();
MutableMap<Integer, String> map = Maps.mutable.of(1, "One", 2, "Two", 3, "Three");
map.forEachKeyValue(new Procedure2<Integer, String>()
{
    public void value(Integer key, String value)
    {
        result.add(key + value);
    }
});
Assert.assertEquals(Bags.mutable.of("1One", "2Two", "3Three"), result);
, если вас интересуют только ключи /значения карты, а не другие.     
51
2008-09-05 22: 27: 52Z

С коллекциями Eclipse (ранее GS Collections ), вы можете использовать метод forEachKeyValue в MapIterable , который наследуется интерфейсами MutableMap и ImmutableMap и их реализации.

MutableBag<String> result = Bags.mutable.empty();
MutableMap<Integer, String> map = Maps.mutable.of(1, "One", 2, "Two", 3, "Three");
map.forEachKeyValue((key, value) -> result.add(key + value));
Assert.assertEquals(Bags.mutable.of("1One", "2Two", "3Three"), result);

С помощью лямбда-синтаксиса Java 8 вы можете написать код следующим образом:

map.entrySet()

Примечание. Я являюсь коммиттером для коллекций Eclipse.

    
32
2018-09-13 01: 25: 34Z

Теоретически, наиболее эффективный способ будет зависеть от того, какая реализация Map. Официальный способ сделать это - вызвать Map.Entry, который возвращает набор entry.getKey(), каждый из которых содержит ключ и значение (entry.getValue() и map.keySet()).

В своеобразной реализации может иметь значение, используете ли вы map.entrySet(), valueSet() или что-то еще. Но я не могу придумать причину, по которой кто-то так написал бы. Скорее всего, это не имеет значения для производительности, что вы делаете.

И да, порядок будет зависеть от реализации, а также (возможно) порядка вставки и других трудно контролируемых факторов.

[править] Я написал entrySet() изначально, но, конечно,

myMap.entrySet().stream().forEach((entry) -> {
    Object currentKey = entry.getKey();
    Object currentValue = entry.getValue();
});
- это действительно ответ.     
29
2017-05-04 22: 39: 46Z

Java 8:

Вы можете использовать лямбда-выражения:

myMap.forEach( (currentKey,currentValue) -> /* action */ );

Для получения дополнительной информации следуйте этой .

    
27
2018-02-06 03: 37: 46Z
  1. @ injecteer: кажется мотивом лямбда-выражений
    2014-08-21 19: 49: 06Z
  2. Вам не нужен поток, если вы просто хотите перебрать карту.
    for( Iterator entries = myMap.entrySet().iterator(); entries.hasNext();){
    
      Entry entry = (Entry) entries.next();
    
      System.out.println(entry.getKey() + "/" + entry.getValue());
    
      //...
    }
    
    гораздо более лаконичен.
    2016-11-09 12: 37: 24Z

Попробуйте это с Java 1.4:

map.forEach((k, v) -> System.out.println((k + ":" + v)));
    
26
2013-06-07 14: 34: 44Z

С Java 8

forEach     
26
2018-05-03 11: 25: 07Z

Java 8

У нас есть метод

Map<String,String> sample = new HashMap<>();
sample.put("A","Apple");
sample.put("B", "Ball");
, который принимает лямбда-выражение . У нас также есть поток API. Рассмотрим карту:
sample.keySet().forEach((k) -> System.out.println(k));

Перебор ключей:

sample.values().forEach((v) -> System.out.println(v));

Итерация по значениям:

sample.forEach((k,v) -> System.out.println(k + ":" + v)); 
sample.entrySet().stream().forEach((entry) -> {
            Object currentKey = entry.getKey();
            Object currentValue = entry.getValue();
            System.out.println(currentKey + ":" + currentValue);
        });

Итерация по записям (с использованием forEach и Streams):

parallelStream()

Преимущество потоков заключается в том, что их можно легко распараллелить, если мы захотим. Нам просто нужно использовать stream() вместо forEachOrdered выше.

forEach против forEach с потоками? forEachOrdered не следует порядку встреч (если он определен) и является по своей природе недетерминированным по природе, в отличие от forEach. Таким образом,

HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>();
/*
 *     Logic to put the Key,Value pair in your HashMap hm
 */

// Print the key value pair in one line.

hm.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));

// Just copy and paste above line to your code.
не гарантирует, что заказ будет сохранен. Также проверьте этот для получения дополнительной информации.     
26
2019-04-29 05: 52: 35Z
  

Лямбда , выражение Java 8

В Java 1.8 (Java 8) это стало намного проще благодаря использованию метода forEach из совокупных операций ( потоковые операции ), который похож на итераторы из Iterable Интерфейс.

Просто скопируйте оператор вставки ниже в свой код и переименуйте переменную HashMap из hm в переменную HashMap, чтобы распечатать пару ключ-значение.

HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
    Random rand = new Random(47);
    int i = 0;
    while(i < 5) {
        i++;
        int key = rand.nextInt(20);
        int value = rand.nextInt(50);
        System.out.println("Inserting key: " + key + " Value: " + value);
        Integer imap = hm.put(key, value);
        if( imap == null) {
            System.out.println("Inserted");
        } else {
            System.out.println("Replaced with " + imap);
        }               
    }

    hm.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));

Output:

Inserting key: 18 Value: 5
Inserted
Inserting key: 13 Value: 11
Inserted
Inserting key: 1 Value: 29
Inserted
Inserting key: 8 Value: 0
Inserted
Inserting key: 2 Value: 7
Inserted
key: 1 value:29
key: 18 value:5
key: 2 value:7
key: 8 value:0
key: 13 value:11

Ниже приведен пример кода, который я пытался использовать с помощью лямбда-выражения . Это так круто. Надо попробовать.

Spliterator sit = hm.entrySet().spliterator();

Также можно использовать Spliterator для того же.

keys

UPDATE

Включая ссылки на документацию на Oracle Docs. Подробнее о лямбда перейдите по этой ссылке и должен прочитать Агрегированные операции , и для Spliterator перейдите по этой ссылке ссылка .

    
26
2019-04-30 13: 05: 59Z

В Map можно выполнять итерации по values и /или both (e.g., entrySet) и /или keys -> keySet(), в зависимости от того, кто им заинтересован. Like:

1.) Выполните итерацию по

Map<String, Object> map = ...;

for (String key : map.keySet()) {
    //your Business logic...
}
карты:

values -> values()

2.) Выполните итерацию по

for (Object value : map.values()) {
    //your Business logic...
}
карты:

both -> entrySet()

3.) Выполните итерацию по

for (Map.Entry<String, Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
    //your Business logic...
}
карты:

//1.
for (Map.Entry entry : hm.entrySet()) {
    System.out.print("key,val: ");
    System.out.println(entry.getKey() + "," + entry.getValue());
}

//2.
Iterator iter = hm.keySet().iterator();
while(iter.hasNext()) {
    Integer key = (Integer)iter.next();
    String val = (String)hm.get(key);
    System.out.println("key,val: " + key + "," + val);
}

//3.
Iterator it = hm.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry entry = (Map.Entry) it.next();
    Integer key = (Integer)entry.getKey();
    String val = (String)entry.getValue();
    System.out.println("key,val: " + key + "," + val);
}

Кроме того, есть 3 различных способа итерации через HashMap. Они как показано ниже _

map.entrySet().forEach(System.out::println);
    
23
2014-01-29 12: 35: 03Z

Самый компактный с Java 8:

public class abcd{
    public static void main(String[] args)
    {
       Map<Integer, String> testMap = new HashMap<Integer, String>();
        testMap.put(10, "a");
        testMap.put(20, "b");
        testMap.put(30, "c");
        testMap.put(40, "d");
        for (Integer key:testMap.keySet()) {
            String value=testMap.get(key);
            System.out.println(value);
        }
    }
}
    
19
2018-04-19 12: 32: 20Z
public class abcd {
    public static void main(String[] args)
    {
       Map<Integer, String> testMap = new HashMap<Integer, String>();
        testMap.put(10, "a");
        testMap.put(20, "b");
        testMap.put(30, "c");
        testMap.put(40, "d");
        for (Entry<Integer, String> entry : testMap.entrySet()) {
            Integer key=entry.getKey();
            String value=entry.getValue();
        }
    }
}

ИЛИ р>

Map map = new HashMap();
for (Map.Entry entry : ((Set<Map.Entry>) map.entrySet())) {
    System.out.println(entry.getKey() + "/" + entry.getValue());
}
    
18
2013-06-07 14: 34: 13Z

Если у вас есть общая нетипизированная карта, вы можете использовать:

    Iterator iterator = map.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry element = (Map.Entry)it.next();
        LOGGER.debug("Key: " + element.getKey());
        LOGGER.debug("value: " + element.getValue());    
    }
    
18
2016-03-16 16: 17: 58Z
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());
}
    
12
2016-01-14 20: 58: 30Z

Вы можете сделать это, используя дженерики:

map.entrySet().forEach(entry -> System.out.println(entry.getValue()));
    
11
2016-03-16 15: 54: 24Z

Используйте Java 8:

           //Functional Oprations
            Map<String, String> mapString = new HashMap<>();
            mapString.entrySet().stream().map((entry) -> {
                String mapKey = entry.getKey();
                return entry;
            }).forEach((entry) -> {
                String mapValue = entry.getValue();
            });

            //Intrator
            Map<String, String> mapString = new HashMap<>();
            for (Iterator<Map.Entry<String, String>> it = mapString.entrySet().iterator(); it.hasNext();) {
                Map.Entry<String, String> entry = it.next();
                String mapKey = entry.getKey();
                String mapValue = entry.getValue();
            }

            //Simple for loop
            Map<String, String> mapString = new HashMap<>();
            for (Map.Entry<String, String> entry : mapString.entrySet()) {
                String mapKey = entry.getKey();
                String mapValue = entry.getValue();

            }
    
11
2018-04-17 19: 03: 40Z
  1. Уже есть несколько ответов с одним предложением.
    2018-04-17 19: 06: 39Z
map.forEach((k,v) -> { System.out.println(k + ":" + v); });
    
9
2016-04-13 07: 47: 46Z

Порядок всегда будет зависеть от конкретной реализации карты. Используя Java 8, вы можете использовать любой из них:

map.entrySet().forEach((e) -> {
            System.out.println(e.getKey() + " : " + e.getValue());
        });

Или:

map.entrySet()
    .stream()
    .filter(e-> e.getValue() > 5)
    .forEach(System.out::println);

Результат будет таким же (в том же порядке). Набор записей поддерживается картой, поэтому вы получаете тот же заказ. Второй удобен тем, что позволяет использовать лямбды, например, если вы хотите печатать только целочисленные объекты, которые больше 5:

public class HMIteration {


    public static void main(String[] args) {
        Map<Object, Object> linkedHashMap = new LinkedHashMap<>();
        Map<Object, Object> hashMap = new HashMap<>();

        for (int i=10; i>=0; i--) {
            linkedHashMap.put(i, i);
            hashMap.put(i, i);
        }

        System.out.println("LinkedHashMap (1): ");
        linkedHashMap.forEach((k,v) -> { System.out.print(k + " (#="+k.hashCode() + "):" + v + ", "); });

        System.out.println("\nLinkedHashMap (2): ");

        linkedHashMap.entrySet().forEach((e) -> {
            System.out.print(e.getKey() + " : " + e.getValue() + ", ");
        });


        System.out.println("\n\nHashMap (1): ");
        hashMap.forEach((k,v) -> { System.out.print(k + " (#:"+k.hashCode() + "):" + v + ", "); });

        System.out.println("\nHashMap (2): ");

        hashMap.entrySet().forEach((e) -> {
            System.out.print(e.getKey() + " : " + e.getValue() + ", ");
        });
    }
}

В приведенном ниже коде показана итерация через LinkedHashMap и обычный HashMap (пример). Вы увидите разницу в порядке:

for (String key : phnMap.keySet()) {
    System.out.println("Key: " + key + " Value: " + phnMap.get(key));
}
  

LinkedHashMap (1):

     

10 (# = 10): 10, 9 (# = 9): 9, 8 (# = 8): 8, 7 (# = 7): 7, 6 (# = 6): 6, 5 ( # = 5): 5, 4 (# = 4): 4, 3 (# = 3): 3, 2 (# = 2): 2, 1 (# = 1): 1, 0 (# = 0): 0, р>      

LinkedHashMap (2):

     

10: 10, 9: 9, 8: 8, 7: 7, 6: 6, 5: 5, 4: 4, 3: 3, 2: 2, 1: 1, 0: 0,

     

HashMap (1):

     

0 (#: 0): 0, 1 (#: 1): 1, 2 (#: 2): 2, 3 (#: 3): 3, 4 (#: 4): 4, 5 ( #: 5): 5, 6 (#: 6): 6, 7 (#: 7): 7, 8 (#: 8): 8, 9 (#: 9): 9, 10 (#: 10): 10, р>      

HashMap (2):

     

0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10,

    
9
2018-03-22 10: 12: 23Z

Эффективное итеративное решение для карты - это цикл для каждого из Java 5 - Java 7. Вот оно:

phnMap.forEach((k,v) -> System.out.println("Key: " + k + " Value: " + v));

В Java 8 вы можете использовать лямбда-выражение для итерации по карте. Это расширенный «forEach»

phnMap.forEach((k,v)->{
    System.out.println("Key: " + k + " Value: " + v);
    if("abc".equals(k)){
        System.out.println("Hello abc");
    }
});
  

Если вы хотите написать условие для лямбды, вы можете написать его так:

Map     
9
2019-01-06 00: 50: 49Z

Да, многие согласились, что это лучший способ перебора nullpointerexception.

Но есть шанс бросить null, если карта null. Не забудьте вставить

                                                 |
                                                 |
                                         - - - -
                                       |
                                       |
for (Map.Entry<String, Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
}
.check. pointer     
8
2018-02-06 22: 40: 17Z
  1. я вижу хороший
    package com.test;
    
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    public class Test {
    
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("ram", "ayodhya");
            map.put("krishan", "mathura");
            map.put("shiv", "kailash");
    
            System.out.println("********* Keys *********");
            Set<String> keys = map.keySet();
            for (String key : keys) {
                System.out.println(key);
            }
    
            System.out.println("********* Values *********");
            Collection<String> values = map.values();
            for (String value : values) {
                System.out.println(value);
            }
    
            System.out.println("***** Keys and Values (Using for each loop) *****");
            for (Map.Entry<String, String> entry : map.entrySet()) {
                System.out.println("Key: " + entry.getKey() + "\t Value: "
                        + entry.getValue());
            }
    
            System.out.println("***** Keys and Values (Using while loop) *****");
            Iterator<Entry<String, String>> entries = map.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry<String, String> entry = (Map.Entry<String, String>) entries
                        .next();
                System.out.println("Key: " + entry.getKey() + "\t Value: "
                        + entry.getValue());
            }
    
            System.out
                    .println("** Keys and Values (Using java 8 using lambdas )***");
            map.forEach((k, v) -> System.out
                    .println("Key: " + k + "\t value: " + v));
        }
    }
    
    2018-03-14 10: 05: 20Z
Map<String, Integer> m = new HashMap<String, Integer>();
    
7
2017-04-06 06: 36: 15Z

Есть много способов сделать это. Ниже приведено несколько простых шагов:

Предположим, у вас есть одна карта типа:

// ********** Using an iterator ****************
Iterator<Entry<String, Integer>> me = m.entrySet().iterator();
while(me.hasNext()){
    Entry<String, Integer> pair = me.next();
    System.out.println(pair.getKey() + ":" + pair.getValue());
}

// *********** Using foreach ************************
for(Entry<String, Integer> me : m.entrySet()){
    System.out.println(me.getKey() + " : " + me.getValue());
}

// *********** Using keySet *****************************
for(String s : m.keySet()){
    System.out.println(s + " : " + m.get(s));
}

// *********** Using keySet and iterator *****************
Iterator<String> me = m.keySet().iterator();
while(me.hasNext()){
    String key = me.next();
    System.out.println(key + " : " + m.get(key));
}

Затем вы можете сделать что-то вроде ниже, чтобы перебрать элементы карты.

    
7
2018-03-22 10: 10: 05Z
источник размещен Вот