在不收集Java8流的情况下对其进行分组

Mat*_*mer 29 java grouping java-8 java-stream

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

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

Tag*_*eev 30

使用标准Stream API无法做到这一点.一般情况下,您无法执行此操作,因为将来可能会出现属于任何已创建组的新项目,因此在处理所有输入之前,您无法将组传递给下游分析.

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

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

其他部分减少操作包括intervalMap,runLengths()等等.

所有部分还原操作都是惰性的,并行友好且非常有效.

请注意,您可以StreamEx使用常规Java 8流轻松构造对象StreamEx.of(stream).还有一些方法可以从数组,Collection,Reader等构建它.StreamEx该类实现Stream接口并与标准Stream API 100%兼容.

  • 嗯,有趣.非常高兴看到这适用于OP的实际代码@MatthiasWimmer (2认同)