用谓词限制流

用谓词限制流

是否存在限制(潜在无限)的Java 8流操作?Stream直到第一个元素不能匹配谓词?

在Java 9中,我们可以使用takeWhile如下面的示例所示,打印小于10的所有数字。

IntStream
    .iterate(1, n -> n + 1)
    .takeWhile(n -> n < 10)
    .forEach(System.out::println);

由于Java 8中没有这样的操作,以一般方式实现它的最佳方法是什么?


临摹微笑
浏览 365回答 3
3回答

慕尼黑8549860

这样的行动应该是可能使用Java 8Stream,但不一定能高效地完成-例如,您不一定能够并行化这样的操作,因为您必须按顺序查看元素。API并不提供一种简单的方法来实现它,但是最简单的方法可能是Stream.iterator(),将Iterator的实现,然后返回到Spliterator然后Stream..或者-也许-包好Spliterator,尽管在这个实现中它不能再被分割了。这里有一个未经测试的实现takeWhile在.上Spliterator:static&nbsp;<T>&nbsp;Spliterator<T>&nbsp;takeWhile( &nbsp;&nbsp;&nbsp;&nbsp;Spliterator<T>&nbsp;splitr,&nbsp;Predicate<?&nbsp;super&nbsp;T>&nbsp;predicate)&nbsp;{ &nbsp;&nbsp;return&nbsp;new&nbsp;Spliterators.AbstractSpliterator<T>(splitr.estimateSize(),&nbsp;0)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;boolean&nbsp;stillGoing&nbsp;=&nbsp;true; &nbsp;&nbsp;&nbsp;&nbsp;@Override&nbsp;public&nbsp;boolean&nbsp;tryAdvance(Consumer<?&nbsp;super&nbsp;T>&nbsp;consumer)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(stillGoing)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boolean&nbsp;hadNext&nbsp;=&nbsp;splitr.tryAdvance(elem&nbsp;->&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(predicate.test(elem))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;consumer.accept(elem); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stillGoing&nbsp;=&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;hadNext&nbsp;&&&nbsp;stillGoing; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;};}static&nbsp;<T>&nbsp;Stream<T>&nbsp;takeWhile(Stream<T>&nbsp;stream,&nbsp;Predicate<?&nbsp;super&nbsp;T>&nbsp;predicate)&nbsp;{ &nbsp;&nbsp;&nbsp;return&nbsp;StreamSupport.stream(takeWhile(stream.spliterator(),&nbsp;predicate),&nbsp;false);}

萧十郎

allMatch()是一个短路函数,所以您可以使用它来停止处理。主要的缺点是你必须做两次测试:一次是为了看是否应该处理它,另一次是看是否要继续进行。IntStream &nbsp;&nbsp;&nbsp;&nbsp;.iterate(1,&nbsp;n&nbsp;->&nbsp;n&nbsp;+&nbsp;1) &nbsp;&nbsp;&nbsp;&nbsp;.peek(n->{if&nbsp;(n<10)&nbsp;System.out.println(n);}) &nbsp;&nbsp;&nbsp;&nbsp;.allMatch(n->n&nbsp;<&nbsp;10);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java