如何在 Iterable 上执行 Stream 函数? [复制]
Posted
技术标签:
【中文标题】如何在 Iterable 上执行 Stream 函数? [复制]【英文标题】:How to perform Stream functions on an Iterable? [duplicate] 【发布时间】:2013-12-17 02:14:34 【问题描述】:在 Java 8 中,Stream
类没有任何方法来包装 Iterable
。
相反,我从Iterable
获取Spliterator
,然后从StreamSupport
获取Stream
,如下所示:
boolean parallel = true;
StreamSupport.stream(spliterator(), parallel)
.filter(Row::isEmpty)
.collect(Collectors.toList())
.forEach(this::deleteRow);
是否有其他方法可以在我缺少的 Iterable
上生成 Stream
操作?
【问题讨论】:
你的做法有什么问题?大多数Iterables都是Collection的实例,Collection有stream()和parallelStream()。 那么问题是为什么stream()
没有被拉入Iterable?
在这里回答:***.com/questions/23114015/…
【参考方案1】:
我的类似问题被标记为重复,但这里是我用来避免一些样板的帮助方法:
public static <T> Stream<T> stream(Iterable<T> in)
return StreamSupport.stream(in.spliterator(), false);
public static <T> Stream<T> parallelStream(Iterable<T> in)
return StreamSupport.stream(in.spliterator(), true);
【讨论】:
【参考方案2】:我知道这并不能直接回答您的问题,但是相当数量的 Iterable 源(例如集合)现在也具有将对象作为流获取的方法。
我认为您会遇到这个问题的摩擦是 Iterable 在语义上是串行的,而 Spliterators 旨在用于并行处理。如果 JDK 中还没有提供您感兴趣的底层数据源,那么为您感兴趣的基础数据源实现 Spliterator 可能是一个更好的主意,因为仅使用 Iterable 周围的包装器不会让您获得 Stream API 提供的好处(如并行处理)。
【讨论】:
但是允许collection.stream()
,但不允许iterable.stream()
,同时提供iterable.spliterator()
,背后的逻辑是什么?如果Iterable
没有提供spliterator()
,您的回答将适用。
我猜它是为了阻止而不是禁止。您可以将由迭代器支持的流标记为并行,但您可能看不到好处。
另外,看看 implNote,他们为迭代器添加了 spliterator 方法 @implNote 默认实现通常应该被覆盖。默认实现返回的拆分器的拆分能力很差,没有大小,并且不报告任何拆分器特征。实现类几乎总能提供更好的实现。
a) 使用流比并行计算有更多的好处; b)当然默认的拆分器就是你所说的,当然它应该在一个大小的集合中被覆盖。但实现说明与接口定义无关。我被剥夺了任意Iterable
上的stream
方法,我不得不破解它。
Iterable#spliterator
确实提供了(正如他们所说的“有限”)并行性,这对于许多管道来说实际上非常好——确实非常好。这一事实主要抹黑了您关于Iterable
是“语义连续”的第二点。您的最后一句话以彻头彻尾的谎言告终:我个人一直在使用Iterable
的 default Spliterator 来实现非常好的并行性。【参考方案3】:
您所描述的是从 Iterable 获取流的方式。这就是他们将 spliterator() 方法添加到 Iterable 的原因。我自己也做过同样的转换,还没有看到其他方法。
[更新] 也许这个other answer 会澄清“为什么”。
【讨论】:
为什么他们让我们受苦... :P @SaintHill 因为 java 8 的非官方 moto 是“由学究,为学究”我有点担心这是开源的直接结果。那个,并且需要五年时间才能发货。 哈哈。我仍然很生气,他们无法通过添加像toList
这样的合理默认值来让开发人员的生活更轻松,而无需费力输入 .collect(Collectors.toList()) !!!!
我认为您的意图是静态导入收集器,因此您只需键入 .collect(toList())。在公共 API 中有太多东西可能会在某种程度上成为噪音。我不希望看到所有的 Collectors.* 都附加到流 API。
@Jay 您指向另一个答案的链接解释了一个不同的问题,这就是为什么Stream
本身不是Iterable
。其理由不适用于此处。以上是关于如何在 Iterable 上执行 Stream 函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Iterable<T> 不提供 stream() 和 parallelStream() 方法?