如果您可以使用有限的并行功能,则以下解决方案将起作用:
private static <T> Stream<T> nonEmptyStream( Stream<T> stream, Supplier<RuntimeException> e) { Spliterator<T> it=stream.spliterator(); return StreamSupport.stream(new Spliterator<T>() { 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<T> trySplit() { return null; } public long estimateSize() { return it.estimateSize(); } public int characteristics() { return it.characteristics(); } }, false);}这是一些使用它的示例代码:
List<String> 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的最后一个片段必须意识到,这是引发适当异常的最后一个片段(并且它也无法前进)。因此,我没有在此处添加对拆分的支持。



