当前位置: 首页 > 知识库问答 >
问题:

Java中的有限生成流--如何创建?

谢誉
2023-03-14

在Java中,可以使用stream.generate(supplier)轻松地生成无限流。但是,我需要生成一个最终完成的流。

想象一下,例如,我想要一个目录中所有文件的流。文件的数量可能很大,因此我无法预先收集所有数据并从中创建流(通过collection.stream())。我需要一段一段地生成序列。但是流显然会在某个时候完成,而像(collection()findany())这样的终端操作符需要对其进行操作,因此stream.generate(supplier)在这里不合适。

有没有什么合理的简单方法可以在Java中做到这一点,而不用我自己实现整个流接口呢?

我可以想到一个简单的hack--使用无限的stream.generate(supplier)进行操作,并在所有实际值被取走时提供null或抛出异常。但它会破坏标准流运算符,我只能在知道这种行为的自己的运算符中使用它。

澄清

评论中的人建议使用metakewhile()运算符。我不是这个意思。如何更好地表达问题...我不是在问如何过滤(或限制)现有的流,我是在问如何动态地创建(生成)流,而不预先加载所有元素,但是流的大小有限(事先未知)。

解决方案

    Iterator it = myCustomIteratorThatGeneratesTheSequence();
    StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false);

共有1个答案

林蕴藉
2023-03-14

有没有什么合理的简单方法可以在Java中做到这一点,而不用我自己实现整个流接口呢?

简单的.limit()保证它将终止。但这并不总是足够强大的。

stream工厂方法之后,创建海关流源而不重新实现流处理管道的最简单方法是对java.util.Spliterators.AbstractSpliterator 进行子类化,并将其传递给java.util.stream.StreamSupport.stream(Supplier<?extends Spliterator >,int,boolean)

如果您打算使用并行流,请注意abstractspliterator只产生次优的拆分。如果您对源代码有更多的控制,完全实现spliterator接口可以更好地实现。

例如,下面的代码段将创建一个流,提供无限序列1,2,3....

在该特定示例中,您可以使用intStream.range()

findany()这样的短路操作实际上可以在无限流上完成,只要有任何匹配的元素。

Java9引入了Stream.Iterate来为一些简单的情况生成有限的流。

 类似资料:
  • 问题内容: 在Java中,可以轻松地生成无限流。但是,我需要生成一个最终将完成的流。 想象一下,例如,我想要目录中所有文件的流。文件的数量可能很大,因此我无法预先收集所有数据并通过它们(通过)创建流。我需要逐段生成序列。但是流显然会在某个时刻结束,并且像(或)这样的终端运营商需要对其进行处理,因此不适合在这里使用。 是否有任何合理的简便方法可以用Java实现,而无需自己实现整个Stream接口?

  • 我需要遍历一个形状像树的API。例如,目录结构或讨论线程。它可以通过以下流程进行建模: 如何遍历这些数据?我的工作如下: 然而,由于我使用的是带有缓冲区的流,所以流永远不会完成。 上游完成且缓冲元件已排空时完成 流缓冲器 我多次阅读了图表周期、活跃度和死锁部分,但仍在努力寻找答案。 这将创建一个活动锁: 编辑:我添加了一个git repo来测试你的解决方案https://github.com/Ma

  • 问题内容: 有没有简单的方法就可以使用java-8在没有外部库的情况下创建无限流? 例如在Scala中: 问题答案: 是的,有一个 简单的 方法: 作为用例: 打印出0到198,以2为步长递增。 通用方法是: 后者的用法可能更不常见。

  • 问题内容: 我需要在Java中执行具有特定超时的外部批处理文件。这意味着,如果批处理执行的时间比指定的超时时间长,我需要取消执行。 这是我编写的示例代码: 批处理文件“ wait.bat”是这样的: 如您在代码中看到的,批处理文件将花费25秒完成(main方法的第一行),并且Timer将在5秒后销毁命令。 这是我的代码的输出: 如您在输出中看到的,最后一行(“ Really Done …”)在第5

  • 看看我制作的以下类: 以及它在以下方面的用法: 如果我使用,可能令人惊讶的是,我将永远得不到无限流。 相反,代码将在底层方法中创建时永远循环。 到目前为止,这是纯理论上的,但如果我想首先跳过无限流中的前x个数字,然后用最后的y个数字来限制它,我可以明确地理解它的必要性,如下所示: 代码不会返回一个结果,应该怎么做呢?

  • 在阅读的API时,我错过了很多函数。首先,它建议使用for循环从stream转到。而且我忽略了一个事实,即不是。 如何在Java8中从生成?