如何使用java 8 stream和lambda来flatMap一个groupingBy结果

我有一个包含其他对象列表的对象,我想返回由容器的某些属性映射的包含对象的平面图。 任何一个如果可能只使用流和lambdas?

public class Selling{ String clientName; double total; List products; } public class Product{ String name; String value; } 

让我们来处理一系列操作:

 List operations = new ArrayList(); operations.stream() .filter(s -> s.getTotal > 10) .collect(groupingBy(Selling::getClientName, mapping(Selling::getProducts, toList()); 

结果将是善意的

 Map<String, List<List>> 

但我想像它一样扁平化

 Map<String, List> 

你可以尝试类似的东西:

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

在JDK9中有一个名为flatMapping的新标准收集器,它可以通过以下方式实现:

 public static  Collector flatMapping(Function> mapper, Collector downstream) { BiConsumer downstreamAccumulator = downstream.accumulator(); return Collector.of(downstream.supplier(), (r, t) -> { try (Stream 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])); } 

您可以将其添加到项目中并使用如下:

 operations.stream() .filter(s -> s.getTotal() > 10) .collect(groupingBy(Selling::getClientName, flatMapping(s -> s.getProducts().stream(), toList())));