从一个长流创建流
我想根据 Streams
的内容将单个 Stream
拆分为 Streams
的 Stream
.生成的 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.
我希望能够根据重复的相同数字将 Stream<Integer>
拆分为 Stream<Stream<Integer>>
,只留下流奇数.
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}
需要产生一个包含以下内容的流:
Would need to result in a stream of streams containing:
{{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<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
,而不首先将完整结果存储为 Lists
的 List
.
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 库中已经有类似的东西(第一个链接重定向到在 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).
请注意,您会得到一个 Stream<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]
相关文章