我读过一些如何创建有限Stream ( Java中有限生成流-如何创建?,溪流是如何停止的?)的问题。
建议实现Spliterator的答案。Spliterator将实现如何提供和提供作为下一个元素(tryAdvance)的逻辑。但是还有另外两种非默认的方法trySplit和estimateSize(),我必须实现它们。
JavaDoc of Spliterator说:
用于遍历和划分源元素的对象。例如,
Spliterator所涵盖的元素的来源可以是数组、Collection、IO通道或生成器函数。..。SpliteratorAPI除了支持顺序遍历之外,还支持分解和单元素迭代,从而支持高效的并行遍历。..。
另一方面,我可以实现这样的逻辑:如何在Stream.Builder周围推进到下一个元素,并绕过一个Spliterator。每次预支时,我都会打电话给accept或add,最后是build。所以看起来很简单。
JavaDoc怎么说?
Stream的可变构建器。这允许创建一个Stream,方法是单独生成元素并将它们添加到Builder中(而不需要使用ArrayList作为临时缓冲区的复制开销)。
使用StreamSupport.stream,我可以使用Spliterator来获得Stream。Builder也将提供一个Stream。
什么时候可以使用Stream.Builder?
只有当一个Spliterator不能更有效的时候(例如,因为源不能被分区,并且它的大小不能被估计)?
发布于 2018-09-14 17:23:03
注意,您可以扩展Spliterators.AbstractSpliterator。然后,只有tryAdvance才能实现。
因此,实现Spliterator的复杂性并不高。
基本区别在于,只有在需要新元素时才调用Spliterator的tryAdvance方法。相反,Stream.Builder有一个存储空间,在获得流之前,它将填充所有流元素。
因此,Spliterator是所有类型的惰性评估的首选,以及当您有要遍历的现有存储时,以避免复制数据。
当元素的创建不一致时,构建器是首选,因此不能根据需要表示元素的创建。想想看,如果您不使用Stream.of(…),那么情况就会变得不灵活。
你有Stream.of(a, b, c, d, e),但现在事实证明,c和d是可选的。所以解决办法是
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,或者这个答案,其中没有随机访问的结构(类层次结构)应该以相反的顺序流。
发布于 2018-09-14 17:00:21
另一方面,我可以实现这样的逻辑:如何在Stream.Builder周围推进到下一个元素,并绕过一个Spliterator。每次预支时,我都会打电话给
accept或add,最后是build。所以看起来很简单。
是也不是。这很简单,但我认为您不了解使用模式:
流构建器有一个生命周期,它从构建阶段开始,在此期间可以添加元素,然后转换到构建阶段,之后可能不会添加元素。构建阶段从调用
build()方法开始,该方法创建一个有序的Stream,其元素是按添加的顺序添加到流构建器中的元素。
(爪哇)
特别是不,您不会在任何流前进时调用Stream.Builder's accept或add方法。您需要预先为该流提供所有对象。然后您需要获得一个流,该流将提供先前添加的所有对象。这类似于将所有对象添加到List中,然后调用List的stream()方法。
如果这符合你的目的,而且你实际上可以高效地完成它,那就太棒了!但是,如果您需要根据需要生成元素,无论是否有限制,那么Stream.Builder都无法帮助您。Spliterator可以。
发布于 2021-10-04 15:35:12
Stream.Builder是个用词不当的词,因为不能真正构建流。可以构建的东西是值对象-- dto、数组、集合。因此,如果Stream.Builder被认为是一个缓冲区,它可能有助于更好地理解它,例如:
buffer.add(a)
buffer.add(b)
buffer.stream()这表明它与ArrayList有多相似:
list.add(a)
list.add(b)
list.stream()另一方面,Spliterator是流的基础,允许对数据集(Iterator的改进版本)进行有效的导航。
因此,答案是不应将它们进行比较。将Stream.Builder与Spliterator进行比较与将ArrayList与Spliterator进行比较是一样的。
https://stackoverflow.com/questions/52336068
复制相似问题