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)
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.
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.
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.
In Java HashMap, we can iterate through its keys, values, and key/value mappings.
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()); });
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With