How to use java 8 merge function for n number of hash cards

I need to merge n hashmaps ideally in a loop, as shown below, using java 8 merge or something:

Map 1: {Name:XXX,Phn:123,Work:""}

Map 2: {Name:XXX,Phn:456,Work: xyz}

Map 3: {Name:XXX,Phn:789,Work:""}

I would like to get the output as below:

 { Name:XXX, // if all values for a key are same take one Phn:123/456/789 // merge all non null values for same key Work:xyz // make sure non-null values are never replaced } 

When I try to use putall, like this

 public Map<String,String> mergeOriginalDataMaps(List<Integer> indexList, List<Map<String,String>> originalData) { Map<String,String> tmpMap = new HashMap<String,String> (); for (int index : indexList ) { tmpMap.putAll(originalData.get(index)); } return tmpMap; } 

If the duplicate key value is "" , the previous value is replaced with the new one. I need to concatenate values, not replace them.

+8
java string java-8 java-stream
source share
1 answer

If you have a List<Map<String, String>> that represents a list of maps to merge, you can have

 Map<String, String> result = maps.stream() .flatMap(m -> m.entrySet().stream()) .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping( Map.Entry::getValue, Collectors.collectingAndThen(Collectors.<String>toSet(), s -> String.join("", s)) ) )); 

This flat map maps each map to its stream of records. Then Stream is grouped by the value of each record, and all individual elements with the same key are compared with their value, combined.

The distinctive part becomes possible by first collecting all the values ​​inside a Set .


Code example:

 public static void main(String[] args) { List<Map<String, String>> maps = new ArrayList<>(); maps.add(new HashMap<String, String>(){{ put("Name", "XXX"); put("Phn", "123"); put("Work", ""); }}); maps.add(new HashMap<String, String>(){{ put("Name", "XXX"); put("Phn", "456"); put("Work", "xyz"); }}); maps.add(new HashMap<String, String>(){{ put("Name", "XXX"); put("Phn", "789"); put("Work", ""); }}); Map<String, String> result = maps.stream() .flatMap(m -> m.entrySet().stream()) .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping( Map.Entry::getValue, Collectors.collectingAndThen(Collectors.<String>toSet(), s -> String.join("", s)) ) )); System.out.println(result); // prints "{Phn=123456789, Work=xyz, Name=XXX}" } 
+9
source share

All Articles