在消费者函数抛出异常后,Spliterator是否应该可重用?

the*_*oop 5 java java-8 spliterator

SpliteratorConsumer在其tryAdvanceforEachRemaining方法中采用任意函数.

如果消费者抛出异常,分裂者的状态应该是什么?如果消费者传递给forEachRemaining10个项目之后抛出异常(然后传播并捕获),tryAdvance那么分裂器中的下一个调用是否应返回第11个项目,或者该分裂器是否应该被视为死亡和无效?

javadocs在这一点上含糊不清; 他们只是说任何例外情况都会传播出去,而没有提到分裂者在那之后的状态

And*_*lko 3

我相信失败后你不应该再继续下去。

spliterator 停止工作并且不再迭代元素。即使还有剩余的元素。

特定元素的异常forEachRemaining意味着整个组的计算结束。

横向和分流排气元件;每个 Spliterator 仅对单个批量计算有用。

一个如何Spliterators.ArraySpliterator处理这个问题的例子。

Spliterator<String> spliterator = Arrays.asList("a", "b", "c").spliterator();
System.out.println(spliterator.estimateSize());

try {
    spliterator.forEachRemaining(s -> {
        if (s.equals("b")) {
            throw new IllegalArgumentException();
        }
        System.out.println(s);
    });
} catch (IllegalArgumentException e) {}

System.out.println(spliterator.estimateSize());
spliterator.forEachRemaining(System.out::println);
Run Code Online (Sandbox Code Playgroud)
3
a
0
Run Code Online (Sandbox Code Playgroud)

AFAIK,大多数Spliterator基于集合/数组的工作都是这样的。

  • 更具体地说,大多数具有专用“forEachRemaining”实现的“Spliterator”将其状态读取到局部变量中,然后在实际处理循环中使用局部变量之前将实例状态更改为完全消耗。这样,就意味着无论处理过程中发生什么,都会被完全消耗,即不需要专门处理异常。但请记住,“estimateSize()”不需要反映遍历后更改的状态。 (2认同)