Reputation: 9191
I am trying to merge two LinkedHashMap.. My rule is that if there are duplicates in the key for both maps.. then the values of the 2nd Map should prevail and override the 1st map.
Here is my code:
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class StreamMerge {
public static void main(String[] args) {
LinkedHashMap<String, Object> m1 = new LinkedHashMap<String, Object>();
m1.put("A", "1");
m1.put("B", "2");
m1.put("C", "3");
LinkedHashMap<String, Object> embeddedMap = new LinkedHashMap<String, Object>();
embeddedMap.put("D", "10");
embeddedMap.put("E", "20");
m1.put("embed", embeddedMap);
LinkedHashMap<String, Object> m2 = new LinkedHashMap<String, Object>();
m2.put("A", "1");
m2.put("B", "2");
m2.put("C", "4");
LinkedHashMap<String, Object> embeddedMap2 = new LinkedHashMap<String, Object>();
embeddedMap2.put("D", "10");
embeddedMap2.put("E", "20");
m2.put("embed", embeddedMap2);
m2.put("F", "100");
LinkedHashMap<String, Object> finalMap = (LinkedHashMap<String, Object>)Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
.collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue(), (map1, map2) -> {
System.out.println("m1" + m1.getClass());
System.out.println("m2" + m2.getClass());
return map2;
}));
System.out.println(finalMap);
}
}
My problem, is that when I try to run this.. I am getting this exception.
Exception in thread "main" java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap
at com.oracle.lambda.StreamMerge.main(StreamMerge.java:36)
m1class java.util.LinkedHashMap
m2class java.util.LinkedHashMap
m1class java.util.LinkedHashMap
m2class java.util.LinkedHashMap
m1class java.util.LinkedHashMap
m2class java.util.LinkedHashMap
m1class java.util.LinkedHashMap
m2class java.util.LinkedHashMap
The workaround that I am doing is to cast it to a HashMap
HashMap<String, Object> finalMap = (HashMap<String, Object>)Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
.collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue(), (map1, map2) -> {
System.out.println("m1" + m1.getClass());
System.out.println("m2" + m2.getClass());
return map2;
}));
System.out.println(finalMap);
But the order gets messed up since it is now a HashMap.. 'F" should be at the end.
{A=1, B=2, C=4, F=100, embed={D=10, E=20}}
Is there something wrong in my code?
Upvotes: 2
Views: 398
Reputation: 393801
Collectors.toMap()
is not required to return any specific implementation of the Map
interface. It currently returns a HashMap
, but that's just an implementation detail.
You can force it to return a LinkedHashMap
by calling a different variant:
LinkedHashMap<String, Object> finalMap =
Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
.collect(Collectors.toMap(entry -> entry.getKey(),
entry -> entry.getValue(),
(v1, v2) -> v2,
LinkedHashMap::new));
The output Map
would be printed as:
{A=1, B=2, C=4, embed={D=10, E=20}, F=100}
Upvotes: 2