无法在Iterable上使用Steam.spliterator迭代创建的流(第二次)

时间:2016-05-06 09:01:27

标签: java java-stream spliterator

我无法在使用Steam.spliterator创建的流上进行迭代(第二次)。我找不到相同的文档。

这就是我在做的事情:

我得到一个Iterable作为funciton参数,我正在通过流迭代这个代码:

StreamSupport.stream(values.spliterator(), false)

然后我再次这样做,但第二个根本没有迭代。我花了很多时间调试它,最后将迭代转换为开头的列表。

你们中的任何人都知道原因吗?

编辑:对不起,如果我不清楚,

我没有多次使用该流,我使用相同的Iterable以上述方式生成流。

Iterable是来自MapReduce作业中的reduce。

谢谢, Hareendra

2 个答案:

答案 0 :(得分:0)

Stream是一次性对象。您只能使用一次,而不能多次使用它。如果你想多次使用这些内容,你必须像你一样,将流转换为列表或数组或任何非流动的,然后为你想要做的两件事创建两个新流。

来自JavaDoc of Stream课程:

  

应该只对一个流进行操作(调用中间或终端流操作)。例如,这排除了"分叉"流,其中相同的源提供两个或多个管道,或多个遍历同一个流。

答案 1 :(得分:0)

确保您用于创建Iterable的{​​{1}}实例真正尊重Spliterator合同。有些人错误地认为任何实现Iterable的东西都将作为iterator(),而事实并非如此。要遵守Iterable合同,必须能够多次调用Iterable并且每次都能够使用它进行迭代。

因为从具有iterator()功能的任何内容创建Iterable非常容易,所以我看到了一些制作iterator()展示您提及的行为的案例。例如,人们可以这样做:

Iterable

Stream<String> stream = ... Iterable<String> falseIterable = stream::iterator; 不遵循必需的falseIterable语义,因为作为Iterable的包装的falseIterable.iterator()第二次不会返回可用的stream.iterator(),一次它已被迭代。