Java 8 Stream, getting head and tail

Posted by lyomi on Stack Overflow See other posts from Stack Overflow or by lyomi
Published on 2013-11-06T02:37:41Z Indexed on 2013/11/06 3:54 UTC
Read the original article Hit count: 206

Filed under:
|
|
|

Java 8 introduced a Stream class that resembles Scala's Stream, a powerful lazy construct using which it is possible to do something like this very concisely:

def from(n: Int): Stream[Int] = n #:: from(n+1)

def sieve(s: Stream[Int]): Stream[Int] = {
  s.head #:: sieve(s.tail filter (_ % s.head != 0))
}

val primes = sieve(from(2))

primes takeWhile(_ < 1000) print  // prints all primes less than 1000

I wondered if it is possible to do this in Java 8, so I wrote something like this:

IntStream from(int n) {
    return IntStream.iterate(n, m -> m + 1);
}

IntStream sieve(IntStream s) {
    int head = s.findFirst().getAsInt();
    return IntStream.concat(IntStream.of(head), sieve(s.skip(1).filter(n -> n % head != 0)));
}

IntStream primes = sieve(from(2));
PrimitiveIterator.OfInt it = primes.iterator();

for (int prime = it.nextInt(); prime < 1000; prime = it.nextInt()) {
    System.out.println(prime);
}

Fairly simple, but it produces java.lang.IllegalStateException: stream has already been operated upon or closed because both findFirst() and skip() is a terminal operation on Stream which can be done only once.

I don't really have to use up the stream twice since all I need is the first number in the stream and the rest as another stream, i.e. equivalent of Scala's Stream.head and Stream.tail. Is there a method in Java 8 Stream that I can achieve this?

Thanks.

© Stack Overflow or respective owner

Related posts about java

Related posts about scala