使用收集器收集元素时如何合并列表/集合

时间:2018-11-11 20:46:10

标签: java java-8 java-stream

我正在尝试根据商品名称获取商品评论地图,并且需要

这样的地图
Map<String, Set<String>> productReviewMap;

但是当我尝试获取地图时

Map<String, Set<Set<String>>> productReviewMap

基于以下代码:

Map<String, Set<Set<String>>> productReviewMap = products.stream().collect(
                    Collectors.groupingBy(Product::getName, Collectors.mapping(Product::getReviews, Collectors.toSet())));

如何获取预期的地图。我们在流中使用flatMap,但是如何在收集器中实现它呢?

3 个答案:

答案 0 :(得分:4)

JDK8没有内置的收集器,因此您的选择受到限制:

使用toMap

Map<String, Set<String>> resultSet = 
        products.stream()
                .collect(toMap(Product::getName,
                        p -> new HashSet<>(p.getReviews()),
                        (l, r) -> {
                            l.addAll(r);
                            return l;
                        }));

或使用自定义收集器。请参见here和最后的代码段here

JDK9具有flatMapping,可以按以下方式使用:

这两个:

 Map<String, Set<String>> resultSet = 
        products.stream()
                .collect(groupingBy(Product::getName,
                        mapping(Product::getReviews,
                                flatMapping(Collection::stream,
                                        toSet()))));

或者这个:

Map<String, Set<String>> resultSet = 
       products.stream()
               .collect(groupingBy(Product::getName,
                        flatMapping(s -> s.getReviews().stream(),toSet())));

答案 1 :(得分:0)

尝试一下。这样就行了。
假设您使用的是Java 8。

Map<String,Set<String>> reviewMap = products.stream().collect(Collectors.toMap(Product::getName,Product::getReviews));

答案 2 :(得分:-1)

您的代码中的“产品”是什么?

我举了一个简单的示例,其中的产品只是一个arrayList,它的工作方式如您所愿。 (我还没有实现一个“产品”类,所以它只是p-> p

List<String> products = new ArrayList<>();
Map<String, Set<String>> productReviewMap = new HashMap<>();
final Map<String, Set<String>> collect = products.stream()
  .collect(Collectors.groupingBy(p -> p, Collectors.mapping(p -> p, Collectors.toSet())));