将多个集合流合并为一个集合 - Java 8

38

所以我有一个Stream<Collection<Long>>,通过对另一个流进行一系列转换获得。

我需要做的是将Stream<Collection<Long>>收集到一个Collection<Long>中。

我可以像这样将它们全部收集到一个列表中:

<Stream<Collection<Long>> streamOfCollections = /* get the stream */;

List<Collection<Long>> listOfCollections = streamOfCollections.collect(Collectors.toList());

然后我可以通过遍历那个集合列表将它们合并成一个。

但是,我想象中一定有一种简单的方法可以使用 .map().collect() 将这些集合流合并成一个 Collection<Long>。只是我无法想到如何实现。有什么想法吗?


3
了解一下 flatMap - Sotirios Delimanolis
3个回答

70

通过流上的flatMap方法调用可以实现该功能,它接受一个将Stream项映射到另一个StreamFunction,你可以在其上收集。

在这里,flatMap方法将Stream<Collection<Long>>转换为Stream<Long>,并且collect将它们收集到Collection<Long>中。

Collection<Long> longs = streamOfCollections
    .flatMap( coll -> coll.stream())
    .collect(Collectors.toList());

18
你也可以使用方法引用:.flatMap(Collection::stream) - Alexis C.

15

你可以使用collect并提供一个供应商(即ArrayList::new部分)来实现这一点:

Collection<Long> longs = streamOfCollections.collect(
    ArrayList::new, 
    ArrayList::addAll,
    ArrayList::addAll
);

@Desik 绝对没错 - 这是我现在使用的东西。当时我只是在学习新的流式 API。 - Vivin Paliath
@Desik为什么它的性能比被接受的答案更好? - Jordan Mackie
4
因为中间操作更少,且不会创建临时对象。在这个解决方案中,你不需要在每个集合上调用stream()方法。 - Desik

1

当不需要时,您无需指定类。更好的解决方案是:

Collection<Long> longs = streamOfCollections.collect(
    ArrayList::new,
    Collection::addAll,
    Collection::addAll
);

假如你不需要 ArrayList 而是需要 HashSet,那么你只需要编辑一行代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接