通过谓词限制流 [英] Limit a stream by a predicate
问题描述
是否存在限制(可能是无限的) Stream
的Java 8流操作,直到第一个元素与谓词不匹配为止?
Is there a Java 8 stream operation that limits a (potentially infinite) Stream
until the first element fails to match a predicate?
在Java 9中,我们可以使用 takeWhile
,如下例所示,打印所有小于10的数字。
In Java 9 we can use takeWhile
as in the example below to print all the numbers less than 10.
IntStream
.iterate(1, n -> n + 1)
.takeWhile(n -> n < 10)
.forEach(System.out::println);
由于Java 8中没有这样的操作,以一般方式实现它的最佳方法是什么?
As there is no such operation in Java 8, what's the best way of implementing it in a general way?
推荐答案
这样的操作应该可能与Java 8 流
,但它不一定能有效地完成 - 例如,你不一定能并行化这样的操作,因为你必须按顺序查看元素。
Such an operation ought to be possible with a Java 8 Stream
, but it can't necessarily be done efficiently -- for example, you can't necessarily parallelize such an operation, as you have to look at elements in order.
API没有提供一种简单的方法,但最简单的方法是采用 Stream.iterator()
,包装 Iterator
有一个take-while实现,然后回到 Spliterator
然后再回到流
。或者 - 也许 - 包装 Spliterator
,虽然在这个实现中它不能再被拆分了。
The API doesn't provide an easy way to do it, but what's probably the simplest way is to take Stream.iterator()
, wrap the Iterator
to have a "take-while" implementation, and then go back to a Spliterator
and then a Stream
. Or -- maybe -- wrap the Spliterator
, though it can't really be split anymore in this implementation.
这是在 Spliterator
上 takeWhile
的未经测试的实现:
Here's an untested implementation of takeWhile
on a 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);
}
这篇关于通过谓词限制流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!