【发布时间】:2020-08-19 13:33:48
【问题描述】:
关于流有多个问题,但对于这个用例和在 java 中,没有找到任何问题。
我有大量对象Stream<A> [~100 万个对象]。 StreamA 来自一个文件。
Class A { enum status [Running,queued,Completed], String name }
我想在不使用任何 Collect 语句的情况下将 Stream<A> 拆分为三个流。 Collect 语句将所有内容加载到内存中。
我在这里多次调用 stream.concat 时遇到 StackOverflowException。
Stream.Concat 有 Java Docs 中提到的问题
“实施说明:
从重复连接构造流时要小心。 Accessing an element of a deeply concatenated stream can result in deep call chains, or even StackOverflowException。”
Map<Status, Stream<String>> splitStream = new HashMap<>();
streamA.foreach(aObj ->
Stream<String> statusBasedStream = splitStream.getOrDefault(aObj.status,Stream.of());
splitStream.put(aObj.status, Stream.concat(statusBasedStream, Stream.of(aObj.name)));
在 github 中可以使用自定义流来实现串联的选项很少,但希望使用标准库来解决这个问题。
如果数据较小,将采用此处提到的列表方法 (Split stream into substreams with N elements)
【问题讨论】:
-
"Collect 语句将所有内容加载到内存中。"当然可以,但是将所有内容放入地图也会将所有内容加载到内存中。那里没有懒惰。
-
这感觉像是一个 XY 问题。你真正想达到什么目标?
-
如果不将它们加载到内存中,您将如何处理状态为
Completed的近 100 万个名称? -
@VishwaramSankaran 有 6 个打开的文件有什么问题?这没什么,这是你需要做的。
-
一百万个字符串并不令人印象深刻。当您将所有字符串收集到
Stream.Builder实例中时,您甚至没有意识到所有字符串都在内存中,这一事实表明它们没有实际的堆内存问题。你没有说这个Stream<A>是从哪里来的。此外,还不清楚Stream.concat会遇到什么问题,当您谈论拆分时,这与concat所做的完全相反。
标签: java java-8 java-stream