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

Dev*_*dra 2 java java-8 java-stream

我正在尝试根据他们的名称获取产品评论地图,并且需要像这样的地图

Map<String, Set<String>> productReviewMap;
Run Code Online (Sandbox Code Playgroud)

但是当我尝试获取地图时,我得到了

Map<String, Set<Set<String>>> productReviewMap
Run Code Online (Sandbox Code Playgroud)

基于以下代码:

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

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

Ous*_* D. 5

这个 is 没有内置收集器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;
                        }));
Run Code Online (Sandbox Code Playgroud)

或使用自定义收集器。看到这里和最后一个代码片段在这里

JDK9hasflatMapping和 可以如下使用:

要么是这样:

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

或这个:

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