Back

Explore Courses Blog Tutorials Interview Questions
0 votes
3 views
in Java by (10.2k points)

Is there a Java 8 stream operation that limits a (potentially infinite) Stream until the first element fails to match a predicate?

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);

As there is no such operation in Java 8, what's the best way of implementing it in a general way?

1 Answer

0 votes
by (46k points)

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.

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.

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);

}

Related questions

0 votes
1 answer
0 votes
1 answer
0 votes
1 answer
0 votes
1 answer
0 votes
1 answer

Browse Categories

...