Próbuję przekonwertować stare konwencjonalne dla każdej pętli do java7 na java8 dla każdej pętli dla zestawu pozycji mapy, ale otrzymuję błąd. Oto kod, który próbuję przekonwertować:
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
}
Oto zmiany, które wprowadziłem:
map.forEach( Map.Entry<String, String> entry -> {
System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
});
Próbowałem też to zrobić:
Map.Entry<String, String> entry;
map.forEach(entry -> {
System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue());
});
Ale wciąż napotykam błąd. Pojawia się błąd: Podpis wyrażenia lambda nie jest zgodny z sygnaturą metody interfejsu funkcjonalnegoaccept(String, String)
Map.Entry
instancji dla każdego wpisu; pierwszy podaje klucz i wartość bez tworzenia instancji. DlategoMap.Entry
jest pośrednikiem i można tego uniknąć używając pierwszej wersji.Map
implementacjiMap.Entry
instancje istnieją już przed iteracją i nie trzeba ich tworzyć. Jednak brak konieczności zajmowania sięMap.Entry
w akcji jest korzystny dla czytelności i ma niewielki potencjał dla lepszej wydajności, ponieważ do pobrania klucza i wartości nie są wymagane żadne dodatkowe wywołania metod.Map
implementacji jest to prawdą,ConcurrentHashMap
będąc ważnym kontrprzykładem.ConcurrentHashMap
czas, tymczasowe instancje wejścia są ostatnią rzeczą, o którą należy się martwić. Niemniej jednak zgadzamy się na preferowaniemap.forEach((key, value) -> …);
mimo wszystko…Może najlepszy sposób, aby odpowiedzieć na pytania typu „która wersja jest szybsza, a której użyć?” to zajrzeć do kodu źródłowego:
map.forEach () - z 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 () - z Iterable.java
default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } }
javadoc
To natychmiast ujawnia, że map.forEach () również używa wewnętrznie Map.Entry . Więc nie spodziewałbym się żadnych korzyści w zakresie wydajności przy używaniu map.forEach () nad map.entrySet (). ForEach () . Więc w twoim przypadku odpowiedź naprawdę zależy od twojego osobistego gustu :)
Aby uzyskać pełną listę różnic, zapoznaj się z podanymi linkami javadoc. Miłego kodowania!
źródło
Możesz użyć następującego kodu dla swojego wymagania
map.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));
źródło
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); });
źródło
Stream API
public void iterateStreamAPI(Map<String, Integer> map) { map.entrySet().stream().forEach(e -> System.out.println(e.getKey() + ":"e.getValue())); }
źródło
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());
źródło