分组 Java8 流而不收集它而不

2023-09-07 01:12:27 作者:perpetual

Java 8 中是否有任何方法可以对 java.util.stream.Stream 中的元素进行分组而不收集它们?我希望结果再次成为 Stream .因为我必须处理大量数据甚至无限流,所以我无法先收集数据并再次流式传输结果.

Is there any way in Java 8 to group the elements in a java.util.stream.Stream without collecting them? I want the result to be a Stream again. Because I have to work with a lot of data or even infinite streams, I cannot collect the data first and stream the result again.

所有需要分组的元素在第一个流中都是连续的.因此,我喜欢保持流评估惰性.

All elements that need to be grouped are consecutive in the first stream. Therefore I like to keep the stream evaluation lazy.

推荐答案

没有办法使用标准的 Stream API.一般来说,您不能这样做,因为将来总有可能出现属于任何已创建组的新项目,因此在处理所有输入之前,您不能将您的组传递给下游分析.

There's no way to do it using standard Stream API. In general you cannot do it as it's always possible that new item will appear in future which belongs to any of already created groups, so you cannot pass your group to downstream analysis until you process all the input.

但是,如果您事先知道要分组的项目在输入流中总是相邻的,您可以使用增强 Stream API 的第三方库来解决您的问题.其中一个库是 StreamEx,它是免费的,由我编写.它包含许多部分归约"运算符,它们根据某些谓词将相邻项折叠成单个项.通常你应该提供一个 BiPredicate 来测试两个相邻的项目,如果它们应该被组合在一起,则返回 true.下面列出了一些部分归约操作:

However if you know in advance that items to be grouped are always adjacent in input stream, you can solve your problem using third-party libraries enhancing Stream API. One of such libraries is StreamEx which is free and written by me. It contains a number of "partial reduction" operators which collapse adjacent items into single based on some predicate. Usually you should supply a BiPredicate which tests two adjacent items and returns true if they should be grouped together. Some of partial reduction operations are listed below:

collapse(BiPredicate):用组的第一个元素替换每个组.例如,collapse(Objects::equals) 对于从流中删除相邻的重复项很有用.groupRuns(BiPredicate):将每个组替换为组元素列表(因此StreamEx