对 Java8 流进行分组而不收集它

2022-09-01 00:11:10

在Java 8中,有没有办法在不收集元素的情况下将元素分组到a中?我希望结果再次成为一个。因为我必须处理大量数据甚至无限流,所以我不能先收集数据,然后再流式传输结果。java.util.stream.StreamStream

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


答案 1

使用标准流 API 无法执行此操作。通常,您无法执行此操作,因为将来始终可能会出现属于任何已创建组的新项目,因此在处理所有输入之前,您无法将组传递给下游分析。

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

  • collapse(BiPredicate):将每个组替换为该组的第一个元素。例如,用于从流中删除相邻的重复项。collapse(Objects::equals)
  • groupRuns(BiPredicate):将每个组替换为组元素列表(因此转换为 )。例如,将创建字符串列表流,其中每个列表都包含以相同字母开头的相邻字符串。StreamEx<T>StreamEx<List<T>>stringStream.groupRuns((a, b) -> a.charAt(0) == b.charAt(0))

其他部分约简操作包括 intervalMaprunLengths() 等。

所有部分约简操作都是懒惰的,并行友好的,并且非常有效。

请注意,您可以使用 从常规 Java 8 流轻松构造对象。还有一些方法可以从数组,集合,读取器等构造它。该类实现接口,并与标准流 API 100% 兼容。StreamExStreamEx.of(stream)StreamExStream


答案 2