forEach loop Java 8 for Map entry set


82

Bir harita giriş kümesi için her döngü için java7'yi java8'e kadar her döngü için eski geleneksel dönüştürmeye çalışıyorum, ancak bir hata alıyorum. İşte dönüştürmeye çalıştığım kod:

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

İşte yaptığım değişiklikler:

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

   }); 

Bunu da yapmayı denedim:

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

   });

Ama yine de hatayla karşı karşıya. Bunun için aldığım hata şudur: Lambda ifadesinin imzası, işlevsel arayüz yönteminin imzasıyla eşleşmiyoraccept(String, String)

Yanıtlar:


193

Javadoc'u okuyun : argüman olarak Map<K, V>.forEach()bir bekler BiConsumer<? super K,? super V>ve BiConsumer<T, U>soyut yöntemin imzası accept(T t, U u).

Bu nedenle, argüman olarak iki girdi alan bir lambda ifadesi iletmelisiniz: anahtar ve değer:

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

Kodunuz, haritanın kendisinde değil, haritanın giriş kümesinde forEach () öğesini çağırırsanız çalışır:

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

Harika. Şimdi ikisi de çalışıyor. Ama hangisi daha iyi bir yol? Hangi durumda performans daha iyi olur? @JBNizet
Siddharth Sachdeva

2
İkinci sürüm Map.Entry, her giriş için bir örneği oluşturulmaya zorlar ; ilki size somutlaştırmadan anahtar ve değer verir. Bu nedenle Map.Entrybir aracıdır ve ilk sürümü kullanmaktan kaçınabilirsiniz.
Marko Topolnik

5
@Marko Topolnik: Çoğu Mapuygulama için Map.Entryörnekler yinelemeden önce zaten mevcuttur ve oluşturulmaları gerekmez. Yine de, Map.Entryeylemde uğraşmak zorunda olmamak okunabilirlik açısından bir kazançtır ve anahtarı ve değeri almak için ek bir yöntem çağrısı gerekmediğinden daha iyi performans için küçük bir potansiyele sahiptir.
Holger

2
Ben senin zımni ima stres edeceğiz @Holger: çoğu için, ama hepsi değil , Mapdoğrudur uygulamaları ConcurrentHashMapönemli bir counterexample olmak.
Marko Topolnik

1
@Marko Topolnik: Ancak bir bütün üzerinde yineleme yaparken ConcurrentHashMap, geçici giriş örnekleri endişelenmeniz gereken son şeydir. Yine de, map.forEach((key, value) -> …);yine de tercih etme konusunda anlaşıyoruz …
Holger

13

"Hangi sürüm daha hızlı ve hangisini kullanmalıyım?" Gibi soruları yanıtlamanın belki de en iyi yolu budur. kaynak koduna bakmaktır:

map.forEach () - Map.java'dan

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'dan

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

javadoc

Bu, map.forEach () işlevinin dahili olarak Map.Entry'yi de kullandığını hemen ortaya çıkarır . Bu nedenle map.forEach () ' i map.entrySet (). ForEach () üzerinde kullanmanın herhangi bir performans avantajı beklemem . Yani sizin durumunuzda cevap gerçekten kişisel zevkinize bağlı :)

Farklılıkların tam listesi için lütfen sağlanan javadoc bağlantılarına bakın. Mutlu kodlamalar!


7

İhtiyaçlarınız için aşağıdaki kodu kullanabilirsiniz

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

2
Bu cevap, JB Nizet tarafından 2 yıl önce verilen cevabın bir kısmı ile aynıdır ve ek, yararlı bilgi sağlamaz.
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);
 });

Lütfen cevabınıza bir açıklama ekleyin. Bu, başkalarının cevabınızı kendi ihtiyaçlarına göre uyarlamasına yardımcı olacaktır. Yorumdan .
Wai Ha Lee

0

Akış API'si

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());

Bu kod parçacığı çözüm olabilir, ancak bir açıklama dahil olmak , yayınınızın kalitesini artırmaya gerçekten yardımcı olur. Gelecekte okuyucular için soruyu yanıtlayacağınızı ve bu kişilerin kod önerinizin nedenlerini bilmeyebileceklerini unutmayın.
Neo Anderson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.