Such an operation should be possible with a Java 8 Stream
but it may not necessarily be done efficiently – for example, you may need to parallelize it, as you need to look at the elements in order.
The API doesn’t provide an easy way to do this, but what is probably the simplest way is to take Stream.iterator()
wrap Iterator
to have a “take-while” implementation, and then go back to Spliterator
and then to Stream
. Or, perhaps, wrap Spliterator
although in this implementation it is no longer possible to split it.
Here is an untested implementation of takeWhile
on a Spliterator
:
static Spliterator takeWhile(
Spliterator splitr, Predicate super T> predicate) {
return new Spliterators.AbstractSpliterator(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 Stream takeWhile(Stream stream, Predicate super T> predicate) {
return StreamSupport.stream(takeWhile(stream.spliterator(), predicate), false);
}