forEach loop Java 8 for Map entry set

JavaLambdaJava 8

Java Problem Overview


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)

Java Solutions


Solution 1 - Java

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

Solution 2 - Java

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!

Solution 3 - Java

You can use the following code for your requirement

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

Solution 4 - Java

Below are the tree best ways to do it 1.Iterate with entry set

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

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

3 stream map.entrySet().stream() .forEach(e -> System.out.println(e.getKey() + ":" + e.getValue()));

Solution 5 - Java

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

Solution 6 - Java

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

Solution 7 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSiddharth SachdevaView Question on Stackoverflow
Solution 1 - JavaJB NizetView Answer on Stackoverflow
Solution 2 - JavaEvgeny TugarevView Answer on Stackoverflow
Solution 3 - JavaShridhar SangamkarView Answer on Stackoverflow
Solution 4 - JavasimerbhattiView Answer on Stackoverflow
Solution 5 - JavaPawan PatidarView Answer on Stackoverflow
Solution 6 - Javavaibhav1111View Answer on Stackoverflow
Solution 7 - JavavivekView Answer on Stackoverflow