首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spliterator与Stream.Builder

Spliterator与Stream.Builder
EN

Stack Overflow用户
提问于 2018-09-14 16:37:55
回答 3查看 990关注 0票数 7

我读过一些如何创建有限Stream ( Java中有限生成流-如何创建?溪流是如何停止的?)的问题。

建议实现Spliterator的答案。Spliterator将实现如何提供和提供作为下一个元素(tryAdvance)的逻辑。但是还有另外两种非默认的方法trySplitestimateSize(),我必须实现它们。

JavaDoc of Spliterator说:

用于遍历和划分源元素的对象。例如,Spliterator所涵盖的元素的来源可以是数组、Collection、IO通道或生成器函数。..。Spliterator API除了支持顺序遍历之外,还支持分解和单元素迭代,从而支持高效的并行遍历。..。

另一方面,我可以实现这样的逻辑:如何在Stream.Builder周围推进到下一个元素,并绕过一个Spliterator。每次预支时,我都会打电话给acceptadd,最后是build。所以看起来很简单。

JavaDoc怎么说?

Stream的可变构建器。这允许创建一个Stream,方法是单独生成元素并将它们添加到Builder中(而不需要使用ArrayList作为临时缓冲区的复制开销)。

使用StreamSupport.stream,我可以使用Spliterator来获得StreamBuilder也将提供一个Stream

什么时候可以使用Stream.Builder

只有当一个Spliterator不能更有效的时候(例如,因为源不能被分区,并且它的大小不能被估计)?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-09-14 17:23:03

注意,您可以扩展Spliterators.AbstractSpliterator。然后,只有tryAdvance才能实现。

因此,实现Spliterator的复杂性并不高。

基本区别在于,只有在需要新元素时才调用SpliteratortryAdvance方法。相反,Stream.Builder有一个存储空间,在获得流之前,它将填充所有流元素。

因此,Spliterator是所有类型的惰性评估的首选,以及当您有要遍历的现有存储时,以避免复制数据。

当元素的创建不一致时,构建器是首选,因此不能根据需要表示元素的创建。想想看,如果您不使用Stream.of(…),那么情况就会变得不灵活。

你有Stream.of(a, b, c, d, e),但现在事实证明,cd是可选的。所以解决办法是

代码语言:javascript
复制
Stream.Builder<MyType> builder = Stream.builder();
builder.add(a).add(b);
if(someCondition) builder.add(c).add(d);
builder.add(e).build()
   /* stream operations */

其他用例是这个答案,其中需要一个Consumer来查询现有的分配器,然后将值推回Stream,或者这个答案,其中没有随机访问的结构(类层次结构)应该以相反的顺序流。

票数 7
EN

Stack Overflow用户

发布于 2018-09-14 17:00:21

另一方面,我可以实现这样的逻辑:如何在Stream.Builder周围推进到下一个元素,并绕过一个Spliterator。每次预支时,我都会打电话给acceptadd,最后是build。所以看起来很简单。

是也不是。这很简单,但我认为您不了解使用模式:

流构建器有一个生命周期,它从构建阶段开始,在此期间可以添加元素,然后转换到构建阶段,之后可能不会添加元素。构建阶段从调用build()方法开始,该方法创建一个有序的Stream,其元素是按添加的顺序添加到流构建器中的元素。

(爪哇)

特别是不,您不会在任何流前进时调用Stream.Builder's acceptadd方法。您需要预先为该流提供所有对象。然后您需要获得一个流,该流将提供先前添加的所有对象。这类似于将所有对象添加到List中,然后调用Liststream()方法。

如果这符合你的目的,而且你实际上可以高效地完成它,那就太棒了!但是,如果您需要根据需要生成元素,无论是否有限制,那么Stream.Builder都无法帮助您。Spliterator可以。

票数 3
EN

Stack Overflow用户

发布于 2021-10-04 15:35:12

Stream.Builder是个用词不当的词,因为不能真正构建流。可以构建的东西是值对象-- dto、数组、集合。因此,如果Stream.Builder被认为是一个缓冲区,它可能有助于更好地理解它,例如:

代码语言:javascript
复制
buffer.add(a)
buffer.add(b)
buffer.stream()

这表明它与ArrayList有多相似:

代码语言:javascript
复制
list.add(a)
list.add(b)
list.stream()

另一方面,Spliterator是流的基础,允许对数据集(Iterator的改进版本)进行有效的导航。

因此,答案是不应将它们进行比较。将Stream.Builder与Spliterator进行比较与将ArrayList与Spliterator进行比较是一样的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52336068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档