收集地图流<k,v>到地图<k,列表<v>&gt;

时间:2017-01-11 23:15:57

标签: java java-8 java-stream collectors

我有一个Stream< Map< K, V > >,我正在尝试将这些地图合并在一起,但保留列表中的重复值,因此最终类型为Map< K, List<V> >。有没有办法做到这一点?我知道toMap收集器有一个二进制函数来基本上选择返回哪个值,但它能跟踪转换后的列表吗?

如果aStream< Map< String, Int > >

a.flatMap(map -> map.entrySet().stream()).collect(
    Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (val1, val2) -> ??
);

2 个答案:

答案 0 :(得分:8)

使用groupingBy:请参阅javadoc,但在您的情况下应该是这样的:

a.flatMap(map -> map.entrySet().stream())
 .collect(
   Collectors.groupingBy(
     Map.Entry::getKey, 
     HashMap::new, 
     Collectors.mapping(Map.Entry::getValue, toList())
   )
);

或者:

a.map(Map::entrySet).flatMap(Set::stream)
 .collect(Collectors.groupingBy(
     Map.Entry::getKey, 
     Collectors.mapping(Map.Entry::getValue, toList())
   )
);

答案 1 :(得分:0)

这比groupingBy解决方案有点晦涩,但我只是想指出,通过提供合并功能也可以使用toMap(正如你最初设定的那样):

    a.flatMap(map -> map.entrySet().stream()).collect(
        Collectors.toMap(Map.Entry::getKey,
                entry -> { 
                    List<Integer> list = new ArrayList<>();
                    list.add(entry.getValue());
                    return list;
                },
                (list1, list2) -> {
                    list1.addAll(list2);
                    return list1;
                }));