我需要在循环中理想地合并n个hashmap,如下所示,使用java 8 merge或其他东西:
地图1: <type 'Array[str]'>
地图2:{Name:XXX,Phn:123,Work:""}
地图3:{Name:XXX,Phn:456,Work: xyz}
我想获得如下输出:
{Name:XXX,Phn:789,Work:""}
当我尝试像这样使用putall时
{
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
}
如果重复键的值为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;
}
,则先前的值将替换为新值。我需要连接值而不是替换它们。
答案 0 :(得分:9)
如果您有List<Map<String, String>>
,表示要合并的地图列表,则可以
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))
)
));
此平面将每个地图映射到其条目的流中。然后,Stream按每个条目的值进行分组,所有具有相同键的不同元素将映射到它们的值,并加入。
通过首先收集Set
内的所有值,可以实现不同的部分。
示例代码:
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}"
}