合并两个List值映射

时间:2016-02-25 22:03:17

标签: java java-8 java-stream

有人知道如何与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}]

如果存在,我正在寻找一种非冗长的方式。我知道如何以旧时尚的方式做到这一点。

问候。

3 个答案:

答案 0 :(得分:6)

总体思路与this post相同。您可以从第一个地图创建一个新地图,迭代第二个地图,并通过merge(key, value, remappingFunction)将每个键与第一个地图合并。在发生冲突的情况下,应用重映射功能:在这种情况下,它采用两个列表并合并它们;如果没有冲突,则输入具有给定键和值的条目。

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

答案 1 :(得分:1)

你可以试试这个,逐渐展平结构,直到你有一个地图键的元组流与列表值:

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

另一种选择是使用Collectors.reducing()作为groupingBy的第二个参数来避免列表的内部流式传输,我猜。但是,我会首先考虑接受的答案

答案 2 :(得分:1)

您必须使用设置而不是列表,并且可以这样做:

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)));
相关问题