forEach 루프 Java 8 for Map 항목 세트


82

맵 항목 세트에 대한 각 루프에 대해 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());

   });

그러나 여전히 오류가 있습니다. 이에 대한 오류는 다음과 같습니다. Lambda 식의 서명이 기능적 인터페이스 메서드의 서명과 일치하지 않습니다.accept(String, String)

답변:


191

javadoc 읽기 : as 인수를 Map<K, V>.forEach()예상 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());
}); 

큰. 이제 둘 다 작동합니다. 그러나 어느 것이 더 나은 방법입니까? 어떤 경우 성능이 더 좋을까요? @JBNizet
싯다 르트 나라 얀 Sachdeva

2
두 번째 버전은 Map.Entry각 항목에 대해 인스턴스를 작성하도록합니다. 첫 번째는 인스턴스화없이 키와 값을 제공합니다. 따라서 Map.Entry중개인이며 첫 번째 버전을 사용하는 것을 피할 수 있습니다.
Marko Topolnik 2015 년

5
@Marko Topolnik : 대부분의 Map구현에서 Map.Entry인스턴스는 반복 전에 이미 존재하며 생성 할 필요가 없습니다. 그래도 Map.Entry작업에서 처리 할 필요가 없으면 가독성이 향상되고 키와 값을 검색하는 데 추가 메서드 호출이 필요하지 않으므로 성능이 약간 향상 될 수 있습니다.
Holger

2
나는 당신의 무언의 의미를 강조하고 있습니다 @Holger : 대부분의, 전부는 아니지만 , Map사실이다 구현 ConcurrentHashMap중요한 반증되고있다.
Marko Topolnik

1
@Marko Topolnik :하지만 전체 ConcurrentHashMap. 그럼에도 불구하고, 우리는 선호에 동의 map.forEach((key, value) -> …);... 어쨌든
홀거

13

"어떤 버전이 더 빠르고 어떤 버전을 사용해야합니까?"와 같은 질문에 답하는 가장 좋은 방법 일 수 있습니다. 소스 코드를 살펴 보는 것입니다.

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.entrySet (). forEach ()를 통해 map.forEach () 를 사용하면 성능상의 이점을 기대하지 않습니다 . 따라서 귀하의 경우 대답은 실제로 귀하의 개인적인 취향에 달려 있습니다. :)

차이점의 전체 목록은 제공된 javadoc 링크를 참조하십시오. 즐거운 코딩 되세요!


7

요구 사항에 대해 다음 코드를 사용할 수 있습니다.

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

2
이 답변은 2 년 전 JB Nizet에서 제공 한 답변의 일부와 동일하며 추가로 유용한 정보를 제공하지 않습니다.
Madbreaks

0
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);
 });

답변에 대한 설명을 추가하십시오. 이것은 다른 사람들이 자신의 필요에 따라 귀하의 답변을 조정하는 데 도움이 될 것입니다. 검토에서 .
Wai Ha Lee

0

스트림 API

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

0
String ss = "Pawan kavita kiyansh Patidar Patidar";
    StringBuilder ress = new StringBuilder();
    
    Map<Character, Integer> fre = ss.chars().boxed()
            .collect(Collectors.toMap(k->Character.valueOf((char) k.intValue()),k->1,Integer::sum));
    
      //fre.forEach((k, v) -> System.out.println((k + ":" + v)));
    
    fre.entrySet().forEach(e ->{
            //System.out.println(e.getKey() + ":" + e.getValue());
            //ress.append(String.valueOf(e.getKey())+e.getValue());
        }); 

    fre.forEach((k,v)->{
        //System.out.println("Item : " + k + " Count : " + v);
        ress.append(String.valueOf(k)+String.valueOf(v));
    });
    
    System.out.println(ress.toString());

이 코드 스 니펫이 해결책이 될 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 도움이됩니다. 미래에 독자를 위해 질문에 답하고 있으며 해당 사용자는 코드 제안 이유를 모를 수 있습니다.
Neo Anderson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.