是否存在Java 8流操作来限制(可能是无限的)Stream直到第一个元素与谓词不匹配?
在Java 9中,我们可以takeWhile像下面的示例那样使用它来打印所有小于10的数字。
IntStream .iterate(1, n -> n + 1) .takeWhile(n -> n < 10) .forEach(System.out::println);
由于Java 8中没有这样的操作,以一般方式实现它的最佳方法是什么?
这样的操作在Java 8中应该是可能的Stream,但不一定能有效地完成-例如,您不必并行化这样的操作,因为您必须按顺序查看元素。
Stream
该API并没有提供一种简便的方法,但是最简单的方法可能是采用Stream.iterator(),将其包装Iterator为具有“ take-while”的实现,然后返回到Spliterator然后是a Stream。或者-也许-包装Spliterator,尽管在此实现中它实际上不能再拆分了。
Stream.iterator()
take-while
Spliterator
下面是一个未经测试的执行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); }
操作takeWhile并dropWhile已添加到JDK9。您的示例代码
takeWhile
dropWhile
在JDK 9下编译和运行时,其行为将完全符合您的预期。
JDK 9已发布。可从以下位置下载:JDK 9 Releases。