Подтвердить что ты не робот

ForEach цикл Java 8 для набора карт

Я пытаюсь преобразовать старые обычные для каждого цикла до java7 в java8 для каждого цикла для набора записей карты, но я получаю сообщение об ошибке. Здесь код, который я пытаюсь преобразовать:

for (Map.Entry<String, String> entry : map.entrySet()) {
        System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
    }

Здесь изменения, которые я сделал:

map.forEach( Map.Entry<String, String> entry -> {
       System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());

   }); 

Я тоже пытался это сделать:

Map.Entry<String, String> entry;
   map.forEach(entry -> {
       System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());

   });

Но все еще сталкивается с ошибкой. Ошибка, которую я получаю для этого: Лембда-выражение подписи не соответствует сигнатуре метода функционального интерфейса accept(String, String)

4b9b3361

Ответ 1

Прочитайте javadoc: Map<K, V>.forEach() ожидает a BiConsumer<? super K,? super V> как аргумент, а сигнатура абстрактного метода BiConsumer<T, U> - accept(T t, U u).

Итак, вы должны передать это выражение лямбда, которое принимает два входа в качестве аргумента: ключ и значение:

map.forEach((key, value) -> {
    System.out.println("Key : " + key + " Value : " + value);
});

Ваш код будет работать, если вы вызвали forEach() в наборе записей карты, а не на самой карте:

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

Ответ 2

Возможно, лучший способ ответить на такие вопросы, как "какая версия быстрее и какой из них я должен использовать?" это посмотреть исходный код:

map.forEach() - из Map.java

default void forEach(BiConsumer<? super K, ? super V> action) {
    Objects.requireNonNull(action);
    for (Map.Entry<K, V> entry : entrySet()) {
        K k;
        V v;
        try {
            k = entry.getKey();
            v = entry.getValue();
        } catch(IllegalStateException ise) {
            // this usually means the entry is no longer in the map.
            throw new ConcurrentModificationException(ise);
        }
        action.accept(k, v);
    }
}

javadoc

map.entrySet(). forEach() - из Iterable.java

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

javadoc

Это немедленно показывает, что map.forEach() также использует Map.Entry внутренне. Поэтому я не ожидал бы каких-либо преимуществ при использовании map.forEach() над map.entrySet(). ForEach(). Так что в вашем случае ответ действительно зависит от вашего личного вкуса:)

Полный список различий см. в приведенных ссылках javadoc. Счастливое кодирование!

Ответ 3

Для вашего требования вы можете использовать следующий код

map.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));

Ответ 4

HashMap<String,Integer> hm = new HashMap();

 hm.put("A",1);
 hm.put("B",2);
 hm.put("C",3);
 hm.put("D",4);

 hm.forEach((key,value)->{
     System.out.println("Key: "+key + " value: "+value);
 });

Ответ 5

API потоков

public void iterateStreamAPI(Map<String, Integer> map) {
    map.entrySet().stream().forEach(e -> System.out.println(e.getKey() + ":"e.getValue()));
}