[英]Java8 : how to aggregate objects from a stream?
如何从有序流中聚合项目,最好是在中间操作中?
按照我的另一个问题: Java8 流线和聚合与终端线上的行动
我有一个非常大的表格文件:
MASTER_REF1
SUBREF1
SUBREF2
SUBREF3
MASTER_REF2
MASTER_REF3
SUBREF1
...
其中 SUBREF(如果有)适用于 MASTER_REF 并且两者都是复杂对象(你可以想象它有点像JSON)。
乍一看,我尝试使用在聚合时返回null
的操作对行进行分组,并在可以找到一组行时返回一个值(如果line.charAt(0)!=' '
则“一组”行结束)。
这段代码很难阅读并且需要一个.filter(Objects::nonNull)
。
我认为人们可以利用这一个实现.collect(groupingBy(...))
或.reduce(...)
但这些都是终端的操作是:
正如我在上一个问题的回答中已经指出的那样,可以使用一些提供部分归约操作的第三方库。 其中一个库是我自己开发的StreamEx 。
在 StreamEx 库中,部分归约操作是中间流操作,它在满足某些条件时组合多个输入元素。 通常条件是通过应用于相邻流元素对的BiPredicate
指定的,当元素应该组合在一起时返回true
。 组合元素的最简单方法是通过StreamEx.groupRuns()
方法创建一个List
,如下所示:
Stream<List<String>> records = StreamEx.of(Files.lines(path))
.groupRuns((line1, line2) -> !line2.startsWith("MASTER"));
在这里,当两条相邻行中的第二行以"MASTER"
开头时,我们开始一条新记录(如您的示例所示)。 否则我们继续之前的记录。
请注意,这样的流仍然是惰性的。 在顺序处理中,一次最多创建一个中间List<String>
。 还支持并行处理,尽管将Files.lines
流转换为并行模式很少能提高性能(至少在 Java-9 之前)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.