恕我直言:我认为这不是重复的,因为这两个问题试图以不同的方式解决问题,尤其是因为它们提供的技术技能完全不同(最后,因为我问自己这两个问题)。
如何从有序流中聚合项目,最好在中间操作中进行聚合?
我的另一个问题:Java8流线并在终端线上进行动作聚合
我有一个非常大的格式文件:
MASTER_REF1
SUBREF1
SUBREF2
SUBREF3
MASTER_REF2
MASTER_REF3
SUBREF1
...
SUBREF(如果有)适用于MASTER_REF,并且两者都是复杂的对象(您可以想象它有点像JSON)。
null
乍一看,我试图对行进行分组,并在汇总时返回操作,并在找到一组行时返回一个值(如果,则“行”结束line.charAt(0)!=' '
)。
此代码难以阅读,需要输入.filter(Objects::nonNull)
。
我认为可以使用a.collect(groupingBy(...))
或a来实现这一点,.reduce(...)
但这些是终端操作,即:
正如我在上一个问题的答案中已经指出的那样,可以使用一些提供部分归约操作的第三方库。我自己开发的StreamEx就是此类库之一。
在StreamEx库中,部分归约操作是中间流操作,它在满足某些条件的同时合并了多个输入元素。通常,条件是通过BiPredicate
应用到一对相邻的流元素来指定的,true
当元素应该组合在一起时,返回该对元素。组合元素的最简单方法是制作如下所示的List
viaStreamEx.groupRuns()
方法:
Stream<List<String>> records = StreamEx.of(Files.lines(path))
.groupRuns((line1, line2) -> !line2.startsWith("MASTER"));
在这里,当两条相邻行中的第二行以"MASTER"
(如您的示例)开头时,我们将开始一个新记录。否则,我们继续上一个记录。
请注意,这样的流仍然是惰性的。在顺序处理中,一次最多List<String>
创建一个中间体。还支持并行处理,尽管将Files.lines
流转换为并行模式很少会提高性能(至少在Java-9之前)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句