从一个长流创建流的流 [英] Create stream of streams from one long stream
问题描述
我想将一个 Stream
拆分为流
Streams
基于 Streams
的内容。结果 Stream
应包含部分原始数据流。
I want to split a single Stream
into a Stream
of Streams
based on the contents of the Streams
. The resulting the Stream
should contain part of the original streams' data.
我真正的应用程序更复杂(它将日志行分组在时间间隔列表中),但我的问题是如何处理流,所以这里我询问一个简化的例子。
My real application is more complex (it is grouping log lines that are within a list of time intervals), but my problem is how to handle the streams, so here I ask about a simplified example.
我希望能够拆分流<整数>
到流<流<整数>>
基于重复的相同数字,只留下奇数的流。
I want to be able split a Stream<Integer>
into a Stream<Stream<Integer>>
based on the same number being repeated, only leaving the streams with odd numbers.
例如以下流包含:
{1,1,1 ,2,2,2,3,6,7,7,1,1}
需要产生一串流包含:
{{1,1,1},{3},{7,7},{1,1}}
通过使用过滤器开始(或结束)我可以做的偶数:
Leaving out the even numbers I can do by starting (or ending) with a filter:
Stream<Integer> input = ...;
Straem<Stream<Integer>> output = input.filter(this::isOdd).someOtherOperation();
这是不受欢迎的,因为它意味着每次评估每个输入值,这是可以接受的但我宁愿避免这个。
This is undesired as it would mean evaluating each input value twice, this is acceptable but I would prefer avoiding this.
我当前的解决方案是迭代流的内容并创建一个列出< List< Integer>>
并将其转换为 Stream< Stream< Integer>>
。然而,这意味着完整的结果保存在内存中(这对我的应用程序来说是不受欢迎的。)
My current solution does this iterating over the contents of the stream and creating a List<List<Integer>>
and converting that to a Stream<Stream<Integer>>
. However this means the full result is kept in memory (which is undesired for my application).
我也认为我可以通过编写自己的 Iterator
从流中读取,但我不确定这是如何工作的。
I also think I would be able to pull this of by writing my own Iterator
that reads from the stream, but I am not sure how this would work.
如何将 Stream
转换为 Stream
Streams
基于原始 Stream
的内容,而不是将完整结果存储为 List $首先是c $ c>
列出
。
How can I convert a Stream
into a Stream
of Streams
based on the contents of the original Stream
, without storing the full result in as a List
of Lists
first.
推荐答案
您可能想要实现自己的聚合分裂器来执行此操作。 proton-pack 库中已有类似内容(第一个链接重定向到质子包中实现的链接) )。
You may want to implement your own aggregating spliterator to do this. There's already something similar in the proton-pack library (the first link redirects to the one implemented in proton-pack).
请注意,您获得流< List< Integer>>
(您可以尝试将实施修改为有一个 Stream< Stream< Integer>>
直接,但你总是需要缓冲一小部分元素;取决于窗口的大小;测试你是否应该创建一个新的元素窗口与否)。例如:
Note that you get a Stream<List<Integer>>
(you may try to modify the implementation to have a Stream<Stream<Integer>>
directly, but you always need to buffer a small amount elements; depending on the window's size; to test whether you should create a new window or not). So for example:
StreamUtils.aggregate(Stream.of(1, 1, 1, 2, 2, 2, 3, 6, 7, 7, 1, 1),
Objects::equals)
.forEach(System.out::println);
输出:
[1, 1, 1]
[2, 2, 2]
[3]
[6]
[7, 7]
[1, 1]
这篇关于从一个长流创建流的流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!