我直接使用流分割器来执行我正在编写的库中的低级操作。最近,当我使用流分割器和交错时,我发现了非常奇怪的行为tryAdvance/trySplit
来电。这是演示该问题的简单代码:
import java.util.Arrays;
import java.util.Spliterator;
public class SpliteratorBug {
public static void main(String[] args) {
Integer[][] input = { { 1 }, { 2, 3 }, { 4, 5, 6 }, { 7, 8 }, { 9 } };
Spliterator<Integer> spliterator = Arrays.stream(input).parallel()
.flatMap(Arrays::stream).spliterator();
spliterator.trySplit();
spliterator.tryAdvance(s -> {});
spliterator.trySplit();
spliterator.forEachRemaining(System.out::println);
}
}
输出是
5
6
9
如您所见,在平面映射之后,我应该从以下位置获取连续数字的有序流1
to 9
。我将分离器分开一次,因此它应该跳转到某个中间位置。接下来,我使用其中的一个元素并将其再次拆分。之后我打印所有剩余的元素。我希望我将从流尾部获得几个连续的元素(可能为零元素,也可以)。然而我得到的是5
and 6
,然后突然跳到9
.
我知道目前 JDK 中的分割器不是这样使用的:它们总是在遍历之前分割。然而官方文档 https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html没有明确禁止调用trySplit
after tryAdvance
.
当我使用直接从集合、数组、生成源等创建的 spliterator 时,从未观察到该问题。仅当 spliterator 是从具有中间值的并行流创建时才会观察到该问题flatMap
.
所以问题是:我是否遇到了错误,或者明确禁止某处以这种方式使用 spliterator ?