小编典典
如果您可以使用有限的并行功能,则以下解决方案将起作用:
private static Stream nonEmptyStream(
Stream stream, Supplier e) {
Spliterator it=stream.spliterator();
return StreamSupport.stream(new Spliterator() {
boolean seen;
public boolean tryAdvance(Consumer super T> action) {
boolean r=it.tryAdvance(action);
if(!seen && !r) throw e.get();
seen=true;
return r;
}
public Spliterator trySplit() { return null; }
public long estimateSize() { return it.estimateSize(); }
public int characteristics() { return it.characteristics(); }
}, false);
}
这是一些使用它的示例代码:
List l=Arrays.asList("hello", "world");
nonEmptyStream(l.stream(), ()->new RuntimeException("No strings available"))
.forEach(System.out::println);
nonEmptyStream(l.stream().filter(s->s.startsWith("x")),
()->new RuntimeException("No strings available"))
.forEach(System.out::println);
(有效的)并行执行的问题在于,支持对的拆分Spliterator需要一种线程安全的方式来注意是否有任何片段以线程安全的方式看到了任何值。然后执行tryAdvance的最后一个片段必须意识到,这是引发适当异常的最后一个片段(并且它也无法前进)。因此,我没有在此处添加对拆分的支持。
2020-09-15