how to use java 8 stream and lambda to flatMap a groupingBy result

后端 未结 2 1895
陌清茗
陌清茗 2020-12-17 03:42

I have a object with contains a list of other objects and I want to return a flatmap of the contained objects mapped by some property of the container. Any one if is it poss

相关标签:
2条回答
  • 2020-12-17 04:27

    You could try something like:

    Map<String, List<Product>> res = operations.parallelStream().filter(s -> s.getTotal() > 10)
        .collect(groupingBy(Selling::getClientName, mapping(Selling::getProducts,
            Collector.of(ArrayList::new, List::addAll, (x, y) -> {
                x.addAll(y);
                return x;
            }))));
    
    0 讨论(0)
  • 2020-12-17 04:42

    In JDK9 there's new standard collector called flatMapping which can be implemented in the following way:

    public static <T, U, A, R>
    Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
                                   Collector<? super U, A, R> downstream) {
        BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
        return Collector.of(downstream.supplier(),
                (r, t) -> {
                    try (Stream<? extends U> result = mapper.apply(t)) {
                        if (result != null)
                            result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
                    }
                },
                downstream.combiner(), downstream.finisher(),
                downstream.characteristics().toArray(new Collector.Characteristics[0]));
    }
    

    You can add it to your project and use like this:

    operations.stream()
       .filter(s -> s.getTotal() > 10)
       .collect(groupingBy(Selling::getClientName, 
                  flatMapping(s -> s.getProducts().stream(), toList())));
    
    0 讨论(0)
提交回复
热议问题