是否存在Java 8流操作来限制(可能是无限的)Stream直到第一个元素与谓词不匹配?
Stream
在Java 9中,我们可以使用takeWhile下面的示例来打印所有小于10的数字。
takeWhile
IntStream .iterate(1, n -> n + 1) .takeWhile(n -> n < 10) .forEach(System.out::println);
由于Java 8中没有这样的操作,以一般方式实现它的最佳方法是什么?
操作takeWhile并dropWhile已添加到JDK9。你的示例代码
dropWhile
在JDK 9下编译和运行时,其行为将完全符合你的预期。
JDK 9已发布。可在此处下载:http : //jdk.java.net/9/
这样的操作在Java 8中应该是可能的Stream,但不一定有效地完成-例如,你不必并行化这样的操作,因为你必须按顺序查看元素。
该API并没有提供一种简便的方法,但是最简单的方法可能是将其Stream.iterator()打包,包装Iterator成具有“ take-while”的实现,然后返回到Spliterator然后是a Stream。或者-也许-包装Spliterator,尽管在该实现中它实际上不能再拆分了。
Stream.iterator()
Iterator
“ take-while”
Spliterator
a Stream
下面是一个未经测试的执行takeWhile上Spliterator:
takeWhile上Spliterator
static <T> Spliterator<T> takeWhile( Spliterator<T> splitr, Predicate<? super T> predicate) { return new Spliterators.AbstractSpliterator<T>(splitr.estimateSize(), 0) { boolean stillGoing = true; @Override public boolean tryAdvance(Consumer<? super T> consumer) { if (stillGoing) { boolean hadNext = splitr.tryAdvance(elem -> { if (predicate.test(elem)) { consumer.accept(elem); } else { stillGoing = false; } }); return hadNext && stillGoing; } return false; } }; } static <T> Stream<T> takeWhile(Stream<T> stream, Predicate<? super T> predicate) { return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false); }