收集器加入传入列表

Collector to join incoming lists

我有一个接收收集器的方法。收集器应合并传入列表:

reducing(Lists.newArrayList(), (container, list) -> {
   container.addAll(list);
   return container;
})

这对我来说似乎是一个非常常见的场景,我相信 Java 自己的收集器应该有一些东西来涵盖这个用例,但我不记得是什么了。此外,我希望它 return ImmutableList.

要首先从嵌套集合中获取“扁平化”元素列表,您需要在他们的评论中应用 flatMapping() which takes a function that turns an element to a stream and a collector as second argument. And to get an immutable list apply toUnmodifiableList() as a downstream collector inside the flatMapping() (as already mentioned by racraman and hfontanez,因为他们之前指出此答案的功劳应属于他们).

    List<List<Integer>> nestedList = List.of(
            List.of(1, 2),
            List.of(3, 4)
    );

    nestedList.stream()
            .collect(Collectors.flatMapping(List::stream,
                        Collectors.toUnmodifiableList()))
            .forEach(System.out::println);

输出

1
2
3
4

更常见的 use-case Collector.flatMapping() 是当流的每个元素都持有一个 对集合的引用时 ,而不是集合本身。

考虑以下场景。

我们有 集合 Order。每个 Order 都有一个 id 和一个 collection of Items。我们想从这个 订单集合 中获得一个 map 以便根据 order id 我们可以获得 项目列表 .

在这种情况下,Collector.flatMapping() 是必不可少的,因为通过在流中间应用 flatMap(),我们将无法访问 collect() 中的 orderId。因此,扁平化应该发生在 collect() 操作中。

实现上述逻辑的方法可能如下所示:

public Map<String, List<Item>> getItemsByOrderId(Collection<Order> orders) {
    return orders.stream()
            // some logic here
            .collect(Collectors.groupingBy(Order::getId,
                     Collectors.flatMapping(order ->
                                     order.getItems().stream().filter(somePredicate),
                             Collectors.toList())));
}

我们还可以做flatMap()操作和toList()收集器,将多个传入列表收集到一个结果列表中。

List<String> joinedList = Stream.of(
   asList("1", "2"),
   asList("3", "4")).flatMap(list -> list.stream()
)
.collect(toList());

System.out.println("Printing the list named as joinedList: " + joinedList);

输出:

Printing the list named joinedList: [1, 2, 3, 4]