【问题标题】:Java `Iterator` to `Stream` which consumes the `Iterator` on terminal operationJava `Iterator` 到 `Stream`,它在终端操作上使用 `Iterator`
【发布时间】:2019-05-31 01:30:07
【问题描述】:

假设您有一个惰性填充的Iterator,您想将其转换为Stream。可以假设Iterator中的元素个数是有限的。

可以指示Iterator 跳过元素(通过实现中的skip 方法)以避免不必要的元素生成,但Iterator 的所有元素必须已经被跳过或一旦@ 987654328@已经调用了一个终端操作。

我知道:

StreamSupport.stream(
        Spliterators.spliteratorUnknownSize(
                theIterator, Spliterator.ORDERED), false);

用于从Iterator 生成Stream,但这并不提供跳过或确保消耗所有元素的方法。

是否有任何基本的Stream 实现可以通过相当简单的扩展实现这一点?

考虑到Stream 接口的方法数量之多,委托似乎很混乱,没有承诺哪些将调用哪些其他方法作为其内部实现的一部分,并且所有 JDK 实现都可以用作起点(至少在我使用的 JDK 中)是包私有的,我认为这是有充分理由的(例如,他们不希望 me 扩展它们......)。

【问题讨论】:

  • 没有承诺哪些人会调用哪些其他人作为其内部实现的一部分...这是继承问题,而不是委托问题。您可以使用proxies 来避免某些委托样板文件。顺便说一句,JDK 的skip() 实现是final,所以它不会帮助你扩展它。
  • 所以你有一个Iterator,你想将它转换为Stream,但是一旦在Stream 中调用skip(x),你就不想在@987654340 上生成元素@ 边?这怎么可能? IteratorhasNext/next - 为了能够“跳过”,您需要在其上调用 next,没有其他办法。还有但是这并没有提供跳过或确保消耗所有元素的方法 - 如果终端操作是findFirst 怎么办?并非所有元素都必须取自 Iterator
  • 我认为,最简单和最干净的解决方案是通过onClose​ 注册一个操作,这将强制跳过所有剩余的元素。然后,使用代码必须使用try(...) {},除非在flatMap 上下文中。没有其他方法可以确保使用后的操作。
  • @Eugene 它是Iterator 的一个实现,它也有一个skip 方法。因此(例如)如果您的流带有5limit,则可以跳过前5 个元素之后的所有元素。或者如果您在Stream 上调用skip,则Iterator 可以跳过这些元素。
  • @Holger 我也是这么想的,但是我看不出有一种方法可以允许skip 不在Streamend 元素上。例如(根据上述评论)如果 skip 已在 Stream 上调用。不过,这确实允许解析后一部分以“确保所有元素都已生成”。

标签: java java-8 iterator java-stream


【解决方案1】:

好吧,我在这方面做了一番尝试。这个想法是在读取 json 数组的 gson 时为 Streams 创建一个 TypeAdapter,而不必转换每个元素:

https://github.com/BeUndead/gson-stream

从我的快速测试来看,它可以满足我的所有需求,但几乎可以肯定,我在快速测试它时没有遇到问题。

【讨论】:

  • 静默大量代码用于处理极端情况,即当skip 是该流上的第一个操作时,即即使.limit(a).skip(b) 也不会受益……
  • 它仍然受益于 skip-all-remaining 部分,这是该代码的相当一部分。唯一特定于跳过第一个操作的位是Stream 委托的SkippingDelegatingSkippableIteratorskip 方法。但是,是的,我同意理想情况下我希望在那里获得好处,但是如果不重写相当大的 JDK Stream 类块,它看起来不会发生。
  • 好吧,“跳过所有剩余部分”是通过onClose 注册操作来完成的,这可以用更少的代码完成,而无需实现您自己的Stream。所以大部分代码都是用于不太有用的功能。
  • 公平点。老实说,除了跳过方法和构造函数只是右键单击>生成>委托之外,还没有注册那么多代码。
猜你喜欢
  • 1970-01-01
  • 2020-10-21
  • 1970-01-01
  • 1970-01-01
  • 2012-07-23
  • 2011-02-18
  • 1970-01-01
  • 2011-06-30
  • 2020-04-20
相关资源
最近更新 更多