Java Stream:在列表中聚合所有在map()中收到的非空集合

Ask*_*mov 5 java java-stream

我有包含字符串ID的集合idList.函数getCollection为单个ID返回一个项集合(类型为MyType).此外,它可能会返回null.

所以对于来自idList的许多ID,我会得到一些空值和一些集合.

目标是将一组ID的getCollection的所有回复收集到最终List中.

我想象过像

 List<MyType> reply = idList.stream().map(id -> getCollection(id))
       .filter(p -> p != null).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但它似乎不是一个有效的表达.如何使其有效?

此外,这个实现的性能如何?

MD *_*med 5

您需要使用flatMap -

List<MyType> reply = idList.stream()
    .map(id -> getCollection(id))
    .filter(collection -> collection != null)
    .flatMap(Collection::stream)
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

如果您正在考虑操作mapflatMap操作之间的差异,那么您可以参考这个极好的答案-

map 和 flatMap 都可以应用于 Stream,它们都返回一个 Stream。不同之处在于 map 操作为每个输入值生成一个输出值,而 flatMap 操作为每个输入值生成一个任意数量(零个或多个)的值。

这反映在每个操作的参数中。

map 操作采用一个函数,该函数为输入流中的每个值调用并产生一个结果值,该值被发送到输出流。

flatMap 操作采用一个函数,该函数在概念上希望消耗一个值并生成任意数量的值。但是,在 Java 中,方法返回任意数量的值很麻烦,因为方法只能返回零或一个值。可以想象一个 API,其中 flatMap 的 mapper 函数接受一个值并返回一个数组或一个值列表,然后将它们发送到输出。鉴于这是流库,表示任意数量返回值的一种特别合适的方式是让映射器函数本身返回流!映射器返回的流中的值从流中排出并传递到输出流。每次调用映射器函数返回的值的“块”在输出流中根本没有区别,

如果要发送零值,则 flatMap 的映射器函数的典型用途是返回 Stream.empty(),如果要返回多个值,则返回 Stream.of(a, b, c) 之类的东西。但是当然可以返回任何流。