有人知道如何在Java 8中合并两个这种类型的映射吗?
Map<String, List<String>> map1--->["a",{1,2,3}]
Map<String, List<String>> map2--->["a",{4,5,6}]
并获得合并的结果。
Map<String, List<String>> map3--->["a",{1,2,3,4,5,6}]
我正在寻找一种非冗长的方法(如果存在的话)。我知道如何用老式的方式做。
祝好。
有人知道如何在Java 8中合并两个这种类型的映射吗?
Map<String, List<String>> map1--->["a",{1,2,3}]
Map<String, List<String>> map2--->["a",{4,5,6}]
Map<String, List<String>> map3--->["a",{1,2,3,4,5,6}]
我正在寻找一种非冗长的方法(如果存在的话)。我知道如何用老式的方式做。
祝好。
这个方法的基本思路与这篇文章中的相同。你需要从第一个Map创建一个新的Map,然后遍历第二个Map,并使用merge(key, value, remappingFunction)
将每个键与第一个Map合并。如果发生冲突,则应用重新映射函数:在这种情况下,它会取两个列表并将它们合并;如果没有冲突,则会将具有给定键和值的条目放入。
Map<String, List<String>> mx = new HashMap<>(map1);
map2.forEach((k, v) -> mx.merge(k, v, (l1, l2) -> {
List<String> l = new ArrayList<>(l1);
l.addAll(l2);
return l;
}));
(l1, l2) -> Stream.concat(l1.stream(),l2.stream()).collect(toList())
。这是Java目前最简单的方法(不使用第三方库)。 - Holger(l1,l2)->{List<String> l = new ArrayList<>(l1.size()+l2.size()); l.addAll(l1); l.addAll(l2); return l;}
以确保适当的初始容量。但问题是关于“非冗长方式”的... - HolgerMap<K,List<V>> result = Stream.of(map1,map2) // Stream<Map<K,List<V>>>
.flatMap(m -> m.entrySet().stream()) // Stream<Map.Entry<K,List<V>>>
.flatMap(e -> e.getValue().stream() // Inner Stream<V>...
.map(v -> new AbstractMap.SimpleImmutableEntry<>(e.getKey(), v)))
// ...flatmapped into an outer Stream<Map.Entry<K,V>>>
.collect(Collectors.groupingBy(e -> e.getKey(), Collectors.mapping(e -> e.getValue(), Collectors.toList())));
另一个选项是通过在groupingBy的第二个参数中使用Collectors.reducing()来避免列表的内部流式处理。不过,我认为首先应该考虑接受的答案。
你需要使用Set而不是List,可以像这样做:
Map<String, Set<String>> map1--->["a",{1,2,3}]
Map<String, Set<String>> map2--->["a",{4,5,6}]
map1.forEach((k, v) -> v.addAll(map2.get(k) == null : new HashSet<> ? map2.get(k)));
Set
。对于List
来说,情况完全一样。 - Holger
ListMultimap
,那么这只是putAll
。 - Louis Wasserman