Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

forEach loop Java 8 for Map entry set

I'm trying to convert old conventional for each loop till java7 to java8's for each loop for a map entry set but I'm getting an error. Here's the code I'm trying to convert:

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

Here's the changes I have done:

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

I tried doing this as well :

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

But still facing error. The error I'm getting for this is : Lambda expression's signature does not match the signature of the functional interface method accept(String, String)

like image 742
Siddharth Sachdeva Avatar asked Aug 28 '15 06:08

Siddharth Sachdeva


People also ask

How do I iterate a map using forEach in Java 8?

Loop a Map 1.1 Below is a normal way to loop a Map . 1.2 In Java 8, we can use forEach to loop a Map and print out its entries. 1.3 For the Map 's key or value containing null , the forEach will print null . P.S The normal way to loop a Map will print the same above output.

Can we use forEach on map in Java?

The Java HashMap forEach() method is used to perform the specified action to each mapping of the hashmap. Here, hashmap is an object of the HashMap class.

How do I use the map in forEach?

The Map. forEach method is used to loop over the map with the given function and executes the given function over each key-value pair. Parameters: This method accepts four parameters as mentioned above and described below: callback: This is the function that executes on each function call.

Can you iterate through a HashMap Java?

In Java HashMap, we can iterate through its keys, values, and key/value mappings.


2 Answers

Read the javadoc: Map<K, V>.forEach() expects a BiConsumer<? super K,? super V> as argument, and the signature of the BiConsumer<T, U> abstract method is accept(T t, U u).

So you should pass it a lambda expression that takes two inputs as argument: the key and the value:

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

Your code would work if you called forEach() on the entry set of the map, not on the map itself:

map.entrySet().forEach(entry -> {     System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue()); });  
like image 59
JB Nizet Avatar answered Nov 07 '22 02:11

JB Nizet


Maybe the best way to answer the questions like "which version is faster and which one shall I use?" is to look to the source code:

map.forEach() - from 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() - from Iterable.java

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

javadoc

This immediately reveals that map.forEach() is also using Map.Entry internally. So I would not expect any performance benefit in using map.forEach() over the map.entrySet().forEach(). So in your case the answer really depends on your personal taste :)

For the complete list of differences please refer to the provided javadoc links. Happy coding!

like image 34
Evgeny Tugarev Avatar answered Nov 07 '22 03:11

Evgeny Tugarev