Java 8 Stream, getting head and tail









up vote
22
down vote

favorite
7












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


Fairly simple, but it produces java.lang.IllegalStateException: stream has already been operated upon or closed because both findFirst() and skip() are terminal operations 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 use to achieve this?



Thanks.










share|improve this question



















  • 2




    If you want to operate over the stream that way, the best you'll be able to do is probably to wrap its iterator(). (To say nothing of the fact that your implementation isn't actually a proper prime sieve; see e.g. this paper.)
    – Louis Wasserman
    Nov 6 '13 at 2:54










  • I have tried extracting the first number and reconstructing another stream like IntStream.generate(() -> it.next()), but the iterator's hasNext() works eagerly and leads to an infinite recursion.
    – lyomi
    Nov 6 '13 at 3:44











  • Yeah, that's not going to work. Really, this isn't going to work cleanly with Streams at all.
    – Louis Wasserman
    Nov 6 '13 at 6:03










  • See this blog post for an explanation on how to build a lazy sequence by yourself in Java.
    – kiritsuku
    Nov 6 '13 at 10:02










  • I programmed this recently with JDK8, but I built my own stream, since I do not think JDK 8 streams are exactly the same thing as the scala's lazy streams.
    – Edwin Dalorzo
    Nov 6 '13 at 23:10














up vote
22
down vote

favorite
7












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


Fairly simple, but it produces java.lang.IllegalStateException: stream has already been operated upon or closed because both findFirst() and skip() are terminal operations 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 use to achieve this?



Thanks.










share|improve this question



















  • 2




    If you want to operate over the stream that way, the best you'll be able to do is probably to wrap its iterator(). (To say nothing of the fact that your implementation isn't actually a proper prime sieve; see e.g. this paper.)
    – Louis Wasserman
    Nov 6 '13 at 2:54










  • I have tried extracting the first number and reconstructing another stream like IntStream.generate(() -> it.next()), but the iterator's hasNext() works eagerly and leads to an infinite recursion.
    – lyomi
    Nov 6 '13 at 3:44











  • Yeah, that's not going to work. Really, this isn't going to work cleanly with Streams at all.
    – Louis Wasserman
    Nov 6 '13 at 6:03










  • See this blog post for an explanation on how to build a lazy sequence by yourself in Java.
    – kiritsuku
    Nov 6 '13 at 10:02










  • I programmed this recently with JDK8, but I built my own stream, since I do not think JDK 8 streams are exactly the same thing as the scala's lazy streams.
    – Edwin Dalorzo
    Nov 6 '13 at 23:10












up vote
22
down vote

favorite
7









up vote
22
down vote

favorite
7






7





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


Fairly simple, but it produces java.lang.IllegalStateException: stream has already been operated upon or closed because both findFirst() and skip() are terminal operations 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 use to achieve this?



Thanks.










share|improve this question















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


Fairly simple, but it produces java.lang.IllegalStateException: stream has already been operated upon or closed because both findFirst() and skip() are terminal operations 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 use to achieve this?



Thanks.







java scala java-8 java-stream






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 17 '15 at 17:14









Stuart Marks

78.2k25134202




78.2k25134202










asked Nov 6 '13 at 2:37









lyomi

2,01432132




2,01432132







  • 2




    If you want to operate over the stream that way, the best you'll be able to do is probably to wrap its iterator(). (To say nothing of the fact that your implementation isn't actually a proper prime sieve; see e.g. this paper.)
    – Louis Wasserman
    Nov 6 '13 at 2:54










  • I have tried extracting the first number and reconstructing another stream like IntStream.generate(() -> it.next()), but the iterator's hasNext() works eagerly and leads to an infinite recursion.
    – lyomi
    Nov 6 '13 at 3:44











  • Yeah, that's not going to work. Really, this isn't going to work cleanly with Streams at all.
    – Louis Wasserman
    Nov 6 '13 at 6:03










  • See this blog post for an explanation on how to build a lazy sequence by yourself in Java.
    – kiritsuku
    Nov 6 '13 at 10:02










  • I programmed this recently with JDK8, but I built my own stream, since I do not think JDK 8 streams are exactly the same thing as the scala's lazy streams.
    – Edwin Dalorzo
    Nov 6 '13 at 23:10












  • 2




    If you want to operate over the stream that way, the best you'll be able to do is probably to wrap its iterator(). (To say nothing of the fact that your implementation isn't actually a proper prime sieve; see e.g. this paper.)
    – Louis Wasserman
    Nov 6 '13 at 2:54










  • I have tried extracting the first number and reconstructing another stream like IntStream.generate(() -> it.next()), but the iterator's hasNext() works eagerly and leads to an infinite recursion.
    – lyomi
    Nov 6 '13 at 3:44











  • Yeah, that's not going to work. Really, this isn't going to work cleanly with Streams at all.
    – Louis Wasserman
    Nov 6 '13 at 6:03










  • See this blog post for an explanation on how to build a lazy sequence by yourself in Java.
    – kiritsuku
    Nov 6 '13 at 10:02










  • I programmed this recently with JDK8, but I built my own stream, since I do not think JDK 8 streams are exactly the same thing as the scala's lazy streams.
    – Edwin Dalorzo
    Nov 6 '13 at 23:10







2




2




If you want to operate over the stream that way, the best you'll be able to do is probably to wrap its iterator(). (To say nothing of the fact that your implementation isn't actually a proper prime sieve; see e.g. this paper.)
– Louis Wasserman
Nov 6 '13 at 2:54




If you want to operate over the stream that way, the best you'll be able to do is probably to wrap its iterator(). (To say nothing of the fact that your implementation isn't actually a proper prime sieve; see e.g. this paper.)
– Louis Wasserman
Nov 6 '13 at 2:54












I have tried extracting the first number and reconstructing another stream like IntStream.generate(() -> it.next()), but the iterator's hasNext() works eagerly and leads to an infinite recursion.
– lyomi
Nov 6 '13 at 3:44





I have tried extracting the first number and reconstructing another stream like IntStream.generate(() -> it.next()), but the iterator's hasNext() works eagerly and leads to an infinite recursion.
– lyomi
Nov 6 '13 at 3:44













Yeah, that's not going to work. Really, this isn't going to work cleanly with Streams at all.
– Louis Wasserman
Nov 6 '13 at 6:03




Yeah, that's not going to work. Really, this isn't going to work cleanly with Streams at all.
– Louis Wasserman
Nov 6 '13 at 6:03












See this blog post for an explanation on how to build a lazy sequence by yourself in Java.
– kiritsuku
Nov 6 '13 at 10:02




See this blog post for an explanation on how to build a lazy sequence by yourself in Java.
– kiritsuku
Nov 6 '13 at 10:02












I programmed this recently with JDK8, but I built my own stream, since I do not think JDK 8 streams are exactly the same thing as the scala's lazy streams.
– Edwin Dalorzo
Nov 6 '13 at 23:10




I programmed this recently with JDK8, but I built my own stream, since I do not think JDK 8 streams are exactly the same thing as the scala's lazy streams.
– Edwin Dalorzo
Nov 6 '13 at 23:10












9 Answers
9






active

oldest

votes

















up vote
10
down vote



accepted










Even if you hadn’t the problem that you can’t split an IntStream, you code didn’t work because you are invoking your sieve method recursively instead of lazily. So you had an infinity recursion before you could query your resulting stream for the first value.



Splitting an IntStream s into a head and a tail IntStream (which has not yet consumed) is possible:



PrimitiveIterator.OfInt it = s.iterator();
int head = it.nextInt();
IntStream tail = IntStream.generate(it::next).filter(i -> i % head != 0);


At this place you need a construct of invoking sieve on the tail lazily. Stream does not provide that; concat expects existing stream instances as arguments and you can’t construct a stream invoking sieve lazily with a lambda expression as lazy creation works with mutable state only which lambda expressions do not support. If you don’t have a library implementation hiding the mutable state you have to use a mutable object. But once you accept the requirement of mutable state, the solution can be even easier than your first approach:



IntStream primes = from(2).filter(i -> p.test(i)).peek(i -> p = p.and(v -> v % i != 0));

IntPredicate p = x -> true;

IntStream from(int n)

return IntStream.iterate(n, m -> m + 1);



This will recursively create a filter but in the end it doesn’t matter whether you create a tree of IntPredicates or a tree of IntStreams (like with your IntStream.concat approach if it did work). If you don’t like the mutable instance field for the filter you can hide it in an inner class (but not in a lambda expression…).






share|improve this answer






















  • I don't think this works, you can't refer to non-final variables inside lambda expressions.
    – djjeck
    Sep 12 '16 at 23:59






  • 1




    @djjeck: if you refer to the second solution, these are fields, not local variables, and can be modified. The variables of the first example are effectively final. And both examples are tested and proven.
    – Holger
    Sep 13 '16 at 8:21










  • You're right, that works (and you actually mention it in the answer). Thanks for clarifying.
    – djjeck
    Sep 14 '16 at 21:54

















up vote
2
down vote













You can essentially implement it like this:



static <T> Tuple2<Optional<T>, Seq<T>> splitAtHead(Stream<T> stream) 
Iterator<T> it = stream.iterator();
return tuple(it.hasNext() ? Optional.of(it.next()) : Optional.empty(), seq(it));



In the above example, Tuple2 and Seq are types borrowed from jOOλ, a library that we developed for jOOQ integration tests. If you don't want any additional dependencies, you might as well implement them yourself:



class Tuple2<T1, T2> 
final T1 v1;
final T2 v2;

Tuple2(T1 v1, T2 v2)
this.v1 = v1;
this.v2 = v2;


static <T1, T2> Tuple2<T1, T2> tuple(T1 v1, T2 v2)
return new Tuple<>(v1, v2);



static <T> Tuple2<Optional<T>, Stream<T>> splitAtHead(Stream<T> stream)
Iterator<T> it = stream.iterator();
return tuple(
it.hasNext() ? Optional.of(it.next()) : Optional.empty,
StreamSupport.stream(Spliterators.spliteratorUnknownSize(
it, Spliterator.ORDERED
), false)
);






share|improve this answer



























    up vote
    2
    down vote













    The solution below does not do state mutations, except for the head/tail deconstruction of the stream.



    The lazyness is obtained using IntStream.iterate. The class Prime is used to keep the generator state



     import java.util.PrimitiveIterator;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;

    public class Prime
    private final IntStream candidates;
    private final int current;

    private Prime(int current, IntStream candidates)

    this.current = current;
    this.candidates = candidates;


    private Prime next()

    PrimitiveIterator.OfInt it = candidates.filter(n -> n % current != 0).iterator();

    int head = it.next();
    IntStream tail = IntStream.generate(it::next);

    return new Prime(head, tail);


    public static Stream<Integer> stream()
    IntStream possiblePrimes = IntStream.iterate(3, i -> i + 1);

    return Stream.iterate(new Prime(2, possiblePrimes), Prime::next)
    .map(p -> p.current);




    The usage would be this:



    Stream<Integer> first10Primes = Prime.stream().limit(10)





    share|improve this answer




















    • It would be great to avoid the modulo operation and take advantage of the additive nature of the sieve. Something along the lines of IntStream impossiblePrimes = IntStream.iterate(head * head, i -> i + 2 * head);. But sure, it's more primes-related than head/tail-related.
      – charlie
      Jun 28 '16 at 12:20


















    up vote
    2
    down vote













    My StreamEx library has now headTail() operation which solves the problem:



    public static StreamEx<Integer> sieve(StreamEx<Integer> input) 
    return input.headTail((head, tail) ->
    sieve(tail.filter(n -> n % head != 0)).prepend(head));



    The headTail method takes a BiFunction which will be executed at most once during the stream terminal operation execution. So this implementation is lazy: it does not compute anything until traversal starts and computes only as much prime numbers as requested. The BiFunction receives a first stream element head and the stream of the rest elements tail and can modify the tail in any way it wants. You may use it with predefined input:



    sieve(IntStreamEx.range(2, 1000).boxed()).forEach(System.out::println);


    But infinite stream work as well



    sieve(StreamEx.iterate(2, x -> x+1)).takeWhile(x -> x < 1000)
    .forEach(System.out::println);
    // Not the primes till 1000, but 1000 first primes
    sieve(StreamEx.iterate(2, x -> x+1)).limit(1000).forEach(System.out::println);


    There's also alternative solution using headTail and predicate concatenation:



    public static StreamEx<Integer> sieve(StreamEx<Integer> input, IntPredicate isPrime) 
    return input.headTail((head, tail) -> isPrime.test(head)
    ? sieve(tail, isPrime.and(n -> n % head != 0)).prepend(head)
    : sieve(tail, isPrime));


    sieve(StreamEx.iterate(2, x -> x+1), i -> true).limit(1000).forEach(System.out::println);



    It interesting to compare recursive solutions: how many primes they capable to generate.



    @John McClean solution (StreamUtils)



    John McClean solutions are not lazy: you cannot feed them with infinite stream. So I just found by trial-and-error the maximal allowed upper bound (17793) (after that StackOverflowError occurs):



    public void sieveTest()
    sieve(IntStream.range(2, 17793).boxed()).forEach(System.out::println);



    @John McClean solution (Streamable)



    public void sieveTest2()
    sieve(Streamable.range(2, 39990)).forEach(System.out::println);



    Increasing upper limit above 39990 results in StackOverflowError.



    @frhack solution (LazySeq)



    LazySeq<Integer> ints = integers(2);
    LazySeq primes = sieve(ints); // sieve method from @frhack answer
    primes.forEach(p -> System.out.println(p));


    Result: stuck after prime number = 53327 with enormous heap allocation and garbage collection taking more than 90%. It took several minutes to advance from 53323 to 53327, so waiting more seems impractical.



    @vidi solution



    Prime.stream().forEach(System.out::println);


    Result: StackOverflowError after prime number = 134417.



    My solution (StreamEx)



    sieve(StreamEx.iterate(2, x -> x+1)).forEach(System.out::println);


    Result: StackOverflowError after prime number = 236167.



    @frhack solution (rxjava)



    Observable<Integer> primes = Observable.from(()->primesStream.iterator());
    primes.forEach((x) -> System.out.println(x.toString()));


    Result: StackOverflowError after prime number = 367663.



    @Holger solution



    IntStream primes=from(2).filter(i->p.test(i)).peek(i->p=p.and(v->v%i!=0));
    primes.forEach(System.out::println);


    Result: StackOverflowError after prime number = 368089.



    My solution (StreamEx with predicate concatenation)



    sieve(StreamEx.iterate(2, x -> x+1), i -> true).forEach(System.out::println);


    Result: StackOverflowError after prime number = 368287.




    So three solutions involving predicate concatenation win, because each new condition adds only 2 more stack frames. I think, the difference between them is marginal and should not be considered to define a winner. However I like my first StreamEx solution more as it more similar to Scala code.






    share|improve this answer






















    • Could you please add timing comparison of respective solutions? Since they all involve predicate contatenation (just more or less explicit) and the modulo operation, they might score equally, though.
      – charlie
      Jun 28 '16 at 12:06











    • Hey man, great work with this library. We use it fairly extensively. The MoreCollectors.flatMapping was really useful, now it is in Java 9. A lot of things you did here could actually be candidates to the main JDK baseline 10+
      – ailveen
      Oct 19 '17 at 11:12

















    up vote
    1
    down vote













    If you don't mind using 3rd party libraries cyclops-streams, I library I wrote has a number of potential solutions.



    The StreamUtils class has large number of static methods for working directly with java.util.stream.Streams including headAndTail.



    HeadAndTail<Integer> headAndTail = StreamUtils.headAndTail(Stream.of(1,2,3,4));
    int head = headAndTail.head(); //1
    Stream<Integer> tail = headAndTail.tail(); //Stream[2,3,4]


    The Streamable class represents a replayable Stream and works by building a lazy, caching intermediate data-structure. Because it is caching and repayable - head and tail can be implemented directly and separately.



    Streamable<Integer> replayable= Streamable.fromStream(Stream.of(1,2,3,4));
    int head = repayable.head(); //1
    Stream<Integer> tail = replayable.tail(); //Stream[2,3,4]


    cyclops-streams also provides a sequential Stream extension that in turn extends jOOλ and has both Tuple based (from jOOλ) and domain object (HeadAndTail) solutions for head and tail extraction.



    SequenceM.of(1,2,3,4)
    .splitAtHead(); //Tuple[1,SequenceM[2,3,4]

    SequenceM.of(1,2,3,4)
    .headAndTail();


    Update per Tagir's request -> A Java version of the Scala sieve using SequenceM



    public void sieveTest()
    sieve(SequenceM.range(2, 1_000)).forEach(System.out::println);


    SequenceM<Integer> sieve(SequenceM<Integer> s)

    return s.headAndTailOptional().map(ht ->SequenceM.of(ht.head())
    .appendStream(sieve(ht.tail().filter(n -> n % ht.head() != 0))))
    .orElse(SequenceM.of());



    And another version via Streamable



    public void sieveTest2()
    sieve(Streamable.range(2, 1_000)).forEach(System.out::println);


    Streamable<Integer> sieve(Streamable<Integer> s)

    return s.size()==0? Streamable.of() : Streamable.of(s.head())
    .appendStreamable(sieve(s.tail()
    .filter(n -> n % s.head() != 0)));



    Note - neither Streamable of SequenceM have an Empty implementation - hence the size check for Streamable and the use of headAndTailOptional.



    Finally a version using plain java.util.stream.Stream



    import static com.aol.cyclops.streams.StreamUtils.headAndTailOptional;

    public void sieveTest()
    sieve(IntStream.range(2, 1_000).boxed()).forEach(System.out::println);


    Stream<Integer> sieve(Stream<Integer> s)

    return headAndTailOptional(s).map(ht ->Stream.concat(Stream.of(ht.head())
    ,sieve(ht.tail().filter(n -> n % ht.head() != 0))))
    .orElse(Stream.of());



    Another update - a lazy iterative based on @Holger's version using objects rather than primitives (note a primitive version is also possible)



     final Mutable<Predicate<Integer>> predicate = Mutable.of(x->true);
    SequenceM.iterate(2, n->n+1)
    .filter(i->predicate.get().test(i))
    .peek(i->predicate.mutate(p-> p.and(v -> v%i!=0)))
    .limit(100000)
    .forEach(System.out::println);





    share|improve this answer






















    • It would be nice to see the full solution of primes problem using your libraries.
      – Tagir Valeev
      Jan 11 '16 at 9:45










    • Teammate going to play around with implementing a sieve of Eratosthenes with Streamable / SequenceM - will keep you posted.
      – John McClean
      Jan 11 '16 at 10:43






    • 1




      final List<Integer> prime = new ArrayList<>(); SequenceM<Integer> primeNumbers = SequenceM.generate(() -> synchronized (prime) if (prime.isEmpty()) prime.add(2); else int last = prime.get(prime.size() - 1); do int candidate = last; if (!prime.stream().parallel().anyMatch(c -> (candidate) % c == 0)) prime.add(candidate); break; last++; while (true); return prime.get(prime.size() - 1); );
      – Nikita Sapozhnikov
      Jan 12 '16 at 11:02











    • Looks that both solutions are not lazy though. Try sieve(Stream.iterate(2, x -> x+1)).limit(1000) as the source, for example.
      – Tagir Valeev
      Jan 19 '16 at 9:14










    • Yes, the head is evaluated immediately each time, the tail is processed lazily. It's a pretty trivial modification to make the head() method in HeadAndTail evaluate lazily however and one that we will add soon.
      – John McClean
      Jan 19 '16 at 11:37

















    up vote
    0
    down vote













    To get head and tail you need a Lazy Stream implementation. Java 8 stream or RxJava are not suitable.



    You can use for example LazySeq as follows.




    Lazy sequence is always traversed from the beginning using very cheap
    first/rest decomposition (head() and tail())



    LazySeq implements java.util.List interface, thus can be used in
    variety of places. Moreover it also implements Java 8 enhancements to
    collections, namely streams and collectors





    package com.company;

    import com.nurkiewicz.lazyseq.LazySeq;

    public class Main

    public static void main(String args)

    LazySeq<Integer> ints = integers(2);
    LazySeq primes = sieve(ints);
    primes.take(10).forEach(p -> System.out.println(p));



    private static LazySeq<Integer> sieve(LazySeq<Integer> s)
    return LazySeq.cons(s.head(), () -> sieve(s.filter(x -> x % s.head() != 0)));


    private static LazySeq<Integer> integers(int from)
    return LazySeq.cons(from, () -> integers(from + 1));








    share|improve this answer





























      up vote
      0
      down vote













      Here is another recipe using the way suggested by Holger.
      It use RxJava just to add the possibility to use the take(int) method and many others.



      package com.company;

      import rx.Observable;

      import java.util.function.IntPredicate;
      import java.util.stream.IntStream;

      public class Main

      public static void main(String args)

      final IntPredicate p=(x)->true;
      IntStream primesStream=IntStream.iterate(2,n->n+1).filter(i -> p[0].test(i)).peek(i->p[0]=p[0].and(v->v%i!=0) );

      Observable primes = Observable.from(()->primesStream.iterator());

      primes.take(10).forEach((x) -> System.out.println(x.toString()));










      share|improve this answer



























        up vote
        0
        down vote













        There are many interesting suggestions provided here, but if someone needs a solution without dependencies to third party libraries I came up with this:



         import java.util.AbstractMap;
        import java.util.Optional;
        import java.util.Spliterators;
        import java.util.stream.StreamSupport;

        /**
        * Splits a stream in the head element and a tail stream.
        * Parallel streams are not supported.
        *
        * @param stream Stream to split.
        * @param <T> Type of the input stream.
        * @return A map entry where @link Map.Entry#getKey() contains an
        * optional with the first element (head) of the original stream
        * and @link Map.Entry#getValue() the tail of the original stream.
        * @throws IllegalArgumentException for parallel streams.
        */
        public static <T> Map.Entry<Optional<T>, Stream<T>> headAndTail(final Stream<T> stream)
        if (stream.isParallel())
        throw new IllegalArgumentException("parallel streams are not supported");

        final Iterator<T> iterator = stream.iterator();
        return new AbstractMap.SimpleImmutableEntry<>(
        iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty(),
        StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false)
        );






        share|improve this answer



























          up vote
          -1
          down vote













          If you want to get head of a stream, just:



          IntStream.range(1, 5).first();


          If you want to get tail of a stream, just:



          IntStream.range(1, 5).skip(1);


          If you want to get both head and tail of a stream, just:



          IntStream s = IntStream.range(1, 5);
          int head = s.head();
          IntStream tail = s.tail();


          If you want to find the prime, just:



          LongStream.range(2, n)
          .filter(i -> LongStream.range(2, (long) Math.sqrt(i) + 1).noneMatch(j -> i % j == 0))
          .forEach(N::println);


          If you want to know more, go to get AbacusUtil



          Declaration: I'm the developer of AbacusUtil.






          share|improve this answer






















            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f19803058%2fjava-8-stream-getting-head-and-tail%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            9 Answers
            9






            active

            oldest

            votes








            9 Answers
            9






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            10
            down vote



            accepted










            Even if you hadn’t the problem that you can’t split an IntStream, you code didn’t work because you are invoking your sieve method recursively instead of lazily. So you had an infinity recursion before you could query your resulting stream for the first value.



            Splitting an IntStream s into a head and a tail IntStream (which has not yet consumed) is possible:



            PrimitiveIterator.OfInt it = s.iterator();
            int head = it.nextInt();
            IntStream tail = IntStream.generate(it::next).filter(i -> i % head != 0);


            At this place you need a construct of invoking sieve on the tail lazily. Stream does not provide that; concat expects existing stream instances as arguments and you can’t construct a stream invoking sieve lazily with a lambda expression as lazy creation works with mutable state only which lambda expressions do not support. If you don’t have a library implementation hiding the mutable state you have to use a mutable object. But once you accept the requirement of mutable state, the solution can be even easier than your first approach:



            IntStream primes = from(2).filter(i -> p.test(i)).peek(i -> p = p.and(v -> v % i != 0));

            IntPredicate p = x -> true;

            IntStream from(int n)

            return IntStream.iterate(n, m -> m + 1);



            This will recursively create a filter but in the end it doesn’t matter whether you create a tree of IntPredicates or a tree of IntStreams (like with your IntStream.concat approach if it did work). If you don’t like the mutable instance field for the filter you can hide it in an inner class (but not in a lambda expression…).






            share|improve this answer






















            • I don't think this works, you can't refer to non-final variables inside lambda expressions.
              – djjeck
              Sep 12 '16 at 23:59






            • 1




              @djjeck: if you refer to the second solution, these are fields, not local variables, and can be modified. The variables of the first example are effectively final. And both examples are tested and proven.
              – Holger
              Sep 13 '16 at 8:21










            • You're right, that works (and you actually mention it in the answer). Thanks for clarifying.
              – djjeck
              Sep 14 '16 at 21:54














            up vote
            10
            down vote



            accepted










            Even if you hadn’t the problem that you can’t split an IntStream, you code didn’t work because you are invoking your sieve method recursively instead of lazily. So you had an infinity recursion before you could query your resulting stream for the first value.



            Splitting an IntStream s into a head and a tail IntStream (which has not yet consumed) is possible:



            PrimitiveIterator.OfInt it = s.iterator();
            int head = it.nextInt();
            IntStream tail = IntStream.generate(it::next).filter(i -> i % head != 0);


            At this place you need a construct of invoking sieve on the tail lazily. Stream does not provide that; concat expects existing stream instances as arguments and you can’t construct a stream invoking sieve lazily with a lambda expression as lazy creation works with mutable state only which lambda expressions do not support. If you don’t have a library implementation hiding the mutable state you have to use a mutable object. But once you accept the requirement of mutable state, the solution can be even easier than your first approach:



            IntStream primes = from(2).filter(i -> p.test(i)).peek(i -> p = p.and(v -> v % i != 0));

            IntPredicate p = x -> true;

            IntStream from(int n)

            return IntStream.iterate(n, m -> m + 1);



            This will recursively create a filter but in the end it doesn’t matter whether you create a tree of IntPredicates or a tree of IntStreams (like with your IntStream.concat approach if it did work). If you don’t like the mutable instance field for the filter you can hide it in an inner class (but not in a lambda expression…).






            share|improve this answer






















            • I don't think this works, you can't refer to non-final variables inside lambda expressions.
              – djjeck
              Sep 12 '16 at 23:59






            • 1




              @djjeck: if you refer to the second solution, these are fields, not local variables, and can be modified. The variables of the first example are effectively final. And both examples are tested and proven.
              – Holger
              Sep 13 '16 at 8:21










            • You're right, that works (and you actually mention it in the answer). Thanks for clarifying.
              – djjeck
              Sep 14 '16 at 21:54












            up vote
            10
            down vote



            accepted







            up vote
            10
            down vote



            accepted






            Even if you hadn’t the problem that you can’t split an IntStream, you code didn’t work because you are invoking your sieve method recursively instead of lazily. So you had an infinity recursion before you could query your resulting stream for the first value.



            Splitting an IntStream s into a head and a tail IntStream (which has not yet consumed) is possible:



            PrimitiveIterator.OfInt it = s.iterator();
            int head = it.nextInt();
            IntStream tail = IntStream.generate(it::next).filter(i -> i % head != 0);


            At this place you need a construct of invoking sieve on the tail lazily. Stream does not provide that; concat expects existing stream instances as arguments and you can’t construct a stream invoking sieve lazily with a lambda expression as lazy creation works with mutable state only which lambda expressions do not support. If you don’t have a library implementation hiding the mutable state you have to use a mutable object. But once you accept the requirement of mutable state, the solution can be even easier than your first approach:



            IntStream primes = from(2).filter(i -> p.test(i)).peek(i -> p = p.and(v -> v % i != 0));

            IntPredicate p = x -> true;

            IntStream from(int n)

            return IntStream.iterate(n, m -> m + 1);



            This will recursively create a filter but in the end it doesn’t matter whether you create a tree of IntPredicates or a tree of IntStreams (like with your IntStream.concat approach if it did work). If you don’t like the mutable instance field for the filter you can hide it in an inner class (but not in a lambda expression…).






            share|improve this answer














            Even if you hadn’t the problem that you can’t split an IntStream, you code didn’t work because you are invoking your sieve method recursively instead of lazily. So you had an infinity recursion before you could query your resulting stream for the first value.



            Splitting an IntStream s into a head and a tail IntStream (which has not yet consumed) is possible:



            PrimitiveIterator.OfInt it = s.iterator();
            int head = it.nextInt();
            IntStream tail = IntStream.generate(it::next).filter(i -> i % head != 0);


            At this place you need a construct of invoking sieve on the tail lazily. Stream does not provide that; concat expects existing stream instances as arguments and you can’t construct a stream invoking sieve lazily with a lambda expression as lazy creation works with mutable state only which lambda expressions do not support. If you don’t have a library implementation hiding the mutable state you have to use a mutable object. But once you accept the requirement of mutable state, the solution can be even easier than your first approach:



            IntStream primes = from(2).filter(i -> p.test(i)).peek(i -> p = p.and(v -> v % i != 0));

            IntPredicate p = x -> true;

            IntStream from(int n)

            return IntStream.iterate(n, m -> m + 1);



            This will recursively create a filter but in the end it doesn’t matter whether you create a tree of IntPredicates or a tree of IntStreams (like with your IntStream.concat approach if it did work). If you don’t like the mutable instance field for the filter you can hide it in an inner class (but not in a lambda expression…).







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 19 '16 at 14:22









            Clashsoft

            5,78942751




            5,78942751










            answered Nov 15 '13 at 17:40









            Holger

            159k23222425




            159k23222425











            • I don't think this works, you can't refer to non-final variables inside lambda expressions.
              – djjeck
              Sep 12 '16 at 23:59






            • 1




              @djjeck: if you refer to the second solution, these are fields, not local variables, and can be modified. The variables of the first example are effectively final. And both examples are tested and proven.
              – Holger
              Sep 13 '16 at 8:21










            • You're right, that works (and you actually mention it in the answer). Thanks for clarifying.
              – djjeck
              Sep 14 '16 at 21:54
















            • I don't think this works, you can't refer to non-final variables inside lambda expressions.
              – djjeck
              Sep 12 '16 at 23:59






            • 1




              @djjeck: if you refer to the second solution, these are fields, not local variables, and can be modified. The variables of the first example are effectively final. And both examples are tested and proven.
              – Holger
              Sep 13 '16 at 8:21










            • You're right, that works (and you actually mention it in the answer). Thanks for clarifying.
              – djjeck
              Sep 14 '16 at 21:54















            I don't think this works, you can't refer to non-final variables inside lambda expressions.
            – djjeck
            Sep 12 '16 at 23:59




            I don't think this works, you can't refer to non-final variables inside lambda expressions.
            – djjeck
            Sep 12 '16 at 23:59




            1




            1




            @djjeck: if you refer to the second solution, these are fields, not local variables, and can be modified. The variables of the first example are effectively final. And both examples are tested and proven.
            – Holger
            Sep 13 '16 at 8:21




            @djjeck: if you refer to the second solution, these are fields, not local variables, and can be modified. The variables of the first example are effectively final. And both examples are tested and proven.
            – Holger
            Sep 13 '16 at 8:21












            You're right, that works (and you actually mention it in the answer). Thanks for clarifying.
            – djjeck
            Sep 14 '16 at 21:54




            You're right, that works (and you actually mention it in the answer). Thanks for clarifying.
            – djjeck
            Sep 14 '16 at 21:54












            up vote
            2
            down vote













            You can essentially implement it like this:



            static <T> Tuple2<Optional<T>, Seq<T>> splitAtHead(Stream<T> stream) 
            Iterator<T> it = stream.iterator();
            return tuple(it.hasNext() ? Optional.of(it.next()) : Optional.empty(), seq(it));



            In the above example, Tuple2 and Seq are types borrowed from jOOλ, a library that we developed for jOOQ integration tests. If you don't want any additional dependencies, you might as well implement them yourself:



            class Tuple2<T1, T2> 
            final T1 v1;
            final T2 v2;

            Tuple2(T1 v1, T2 v2)
            this.v1 = v1;
            this.v2 = v2;


            static <T1, T2> Tuple2<T1, T2> tuple(T1 v1, T2 v2)
            return new Tuple<>(v1, v2);



            static <T> Tuple2<Optional<T>, Stream<T>> splitAtHead(Stream<T> stream)
            Iterator<T> it = stream.iterator();
            return tuple(
            it.hasNext() ? Optional.of(it.next()) : Optional.empty,
            StreamSupport.stream(Spliterators.spliteratorUnknownSize(
            it, Spliterator.ORDERED
            ), false)
            );






            share|improve this answer
























              up vote
              2
              down vote













              You can essentially implement it like this:



              static <T> Tuple2<Optional<T>, Seq<T>> splitAtHead(Stream<T> stream) 
              Iterator<T> it = stream.iterator();
              return tuple(it.hasNext() ? Optional.of(it.next()) : Optional.empty(), seq(it));



              In the above example, Tuple2 and Seq are types borrowed from jOOλ, a library that we developed for jOOQ integration tests. If you don't want any additional dependencies, you might as well implement them yourself:



              class Tuple2<T1, T2> 
              final T1 v1;
              final T2 v2;

              Tuple2(T1 v1, T2 v2)
              this.v1 = v1;
              this.v2 = v2;


              static <T1, T2> Tuple2<T1, T2> tuple(T1 v1, T2 v2)
              return new Tuple<>(v1, v2);



              static <T> Tuple2<Optional<T>, Stream<T>> splitAtHead(Stream<T> stream)
              Iterator<T> it = stream.iterator();
              return tuple(
              it.hasNext() ? Optional.of(it.next()) : Optional.empty,
              StreamSupport.stream(Spliterators.spliteratorUnknownSize(
              it, Spliterator.ORDERED
              ), false)
              );






              share|improve this answer






















                up vote
                2
                down vote










                up vote
                2
                down vote









                You can essentially implement it like this:



                static <T> Tuple2<Optional<T>, Seq<T>> splitAtHead(Stream<T> stream) 
                Iterator<T> it = stream.iterator();
                return tuple(it.hasNext() ? Optional.of(it.next()) : Optional.empty(), seq(it));



                In the above example, Tuple2 and Seq are types borrowed from jOOλ, a library that we developed for jOOQ integration tests. If you don't want any additional dependencies, you might as well implement them yourself:



                class Tuple2<T1, T2> 
                final T1 v1;
                final T2 v2;

                Tuple2(T1 v1, T2 v2)
                this.v1 = v1;
                this.v2 = v2;


                static <T1, T2> Tuple2<T1, T2> tuple(T1 v1, T2 v2)
                return new Tuple<>(v1, v2);



                static <T> Tuple2<Optional<T>, Stream<T>> splitAtHead(Stream<T> stream)
                Iterator<T> it = stream.iterator();
                return tuple(
                it.hasNext() ? Optional.of(it.next()) : Optional.empty,
                StreamSupport.stream(Spliterators.spliteratorUnknownSize(
                it, Spliterator.ORDERED
                ), false)
                );






                share|improve this answer












                You can essentially implement it like this:



                static <T> Tuple2<Optional<T>, Seq<T>> splitAtHead(Stream<T> stream) 
                Iterator<T> it = stream.iterator();
                return tuple(it.hasNext() ? Optional.of(it.next()) : Optional.empty(), seq(it));



                In the above example, Tuple2 and Seq are types borrowed from jOOλ, a library that we developed for jOOQ integration tests. If you don't want any additional dependencies, you might as well implement them yourself:



                class Tuple2<T1, T2> 
                final T1 v1;
                final T2 v2;

                Tuple2(T1 v1, T2 v2)
                this.v1 = v1;
                this.v2 = v2;


                static <T1, T2> Tuple2<T1, T2> tuple(T1 v1, T2 v2)
                return new Tuple<>(v1, v2);



                static <T> Tuple2<Optional<T>, Stream<T>> splitAtHead(Stream<T> stream)
                Iterator<T> it = stream.iterator();
                return tuple(
                it.hasNext() ? Optional.of(it.next()) : Optional.empty,
                StreamSupport.stream(Spliterators.spliteratorUnknownSize(
                it, Spliterator.ORDERED
                ), false)
                );







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Sep 22 '14 at 14:28









                Lukas Eder

                130k69427925




                130k69427925




















                    up vote
                    2
                    down vote













                    The solution below does not do state mutations, except for the head/tail deconstruction of the stream.



                    The lazyness is obtained using IntStream.iterate. The class Prime is used to keep the generator state



                     import java.util.PrimitiveIterator;
                    import java.util.stream.IntStream;
                    import java.util.stream.Stream;

                    public class Prime
                    private final IntStream candidates;
                    private final int current;

                    private Prime(int current, IntStream candidates)

                    this.current = current;
                    this.candidates = candidates;


                    private Prime next()

                    PrimitiveIterator.OfInt it = candidates.filter(n -> n % current != 0).iterator();

                    int head = it.next();
                    IntStream tail = IntStream.generate(it::next);

                    return new Prime(head, tail);


                    public static Stream<Integer> stream()
                    IntStream possiblePrimes = IntStream.iterate(3, i -> i + 1);

                    return Stream.iterate(new Prime(2, possiblePrimes), Prime::next)
                    .map(p -> p.current);




                    The usage would be this:



                    Stream<Integer> first10Primes = Prime.stream().limit(10)





                    share|improve this answer




















                    • It would be great to avoid the modulo operation and take advantage of the additive nature of the sieve. Something along the lines of IntStream impossiblePrimes = IntStream.iterate(head * head, i -> i + 2 * head);. But sure, it's more primes-related than head/tail-related.
                      – charlie
                      Jun 28 '16 at 12:20















                    up vote
                    2
                    down vote













                    The solution below does not do state mutations, except for the head/tail deconstruction of the stream.



                    The lazyness is obtained using IntStream.iterate. The class Prime is used to keep the generator state



                     import java.util.PrimitiveIterator;
                    import java.util.stream.IntStream;
                    import java.util.stream.Stream;

                    public class Prime
                    private final IntStream candidates;
                    private final int current;

                    private Prime(int current, IntStream candidates)

                    this.current = current;
                    this.candidates = candidates;


                    private Prime next()

                    PrimitiveIterator.OfInt it = candidates.filter(n -> n % current != 0).iterator();

                    int head = it.next();
                    IntStream tail = IntStream.generate(it::next);

                    return new Prime(head, tail);


                    public static Stream<Integer> stream()
                    IntStream possiblePrimes = IntStream.iterate(3, i -> i + 1);

                    return Stream.iterate(new Prime(2, possiblePrimes), Prime::next)
                    .map(p -> p.current);




                    The usage would be this:



                    Stream<Integer> first10Primes = Prime.stream().limit(10)





                    share|improve this answer




















                    • It would be great to avoid the modulo operation and take advantage of the additive nature of the sieve. Something along the lines of IntStream impossiblePrimes = IntStream.iterate(head * head, i -> i + 2 * head);. But sure, it's more primes-related than head/tail-related.
                      – charlie
                      Jun 28 '16 at 12:20













                    up vote
                    2
                    down vote










                    up vote
                    2
                    down vote









                    The solution below does not do state mutations, except for the head/tail deconstruction of the stream.



                    The lazyness is obtained using IntStream.iterate. The class Prime is used to keep the generator state



                     import java.util.PrimitiveIterator;
                    import java.util.stream.IntStream;
                    import java.util.stream.Stream;

                    public class Prime
                    private final IntStream candidates;
                    private final int current;

                    private Prime(int current, IntStream candidates)

                    this.current = current;
                    this.candidates = candidates;


                    private Prime next()

                    PrimitiveIterator.OfInt it = candidates.filter(n -> n % current != 0).iterator();

                    int head = it.next();
                    IntStream tail = IntStream.generate(it::next);

                    return new Prime(head, tail);


                    public static Stream<Integer> stream()
                    IntStream possiblePrimes = IntStream.iterate(3, i -> i + 1);

                    return Stream.iterate(new Prime(2, possiblePrimes), Prime::next)
                    .map(p -> p.current);




                    The usage would be this:



                    Stream<Integer> first10Primes = Prime.stream().limit(10)





                    share|improve this answer












                    The solution below does not do state mutations, except for the head/tail deconstruction of the stream.



                    The lazyness is obtained using IntStream.iterate. The class Prime is used to keep the generator state



                     import java.util.PrimitiveIterator;
                    import java.util.stream.IntStream;
                    import java.util.stream.Stream;

                    public class Prime
                    private final IntStream candidates;
                    private final int current;

                    private Prime(int current, IntStream candidates)

                    this.current = current;
                    this.candidates = candidates;


                    private Prime next()

                    PrimitiveIterator.OfInt it = candidates.filter(n -> n % current != 0).iterator();

                    int head = it.next();
                    IntStream tail = IntStream.generate(it::next);

                    return new Prime(head, tail);


                    public static Stream<Integer> stream()
                    IntStream possiblePrimes = IntStream.iterate(3, i -> i + 1);

                    return Stream.iterate(new Prime(2, possiblePrimes), Prime::next)
                    .map(p -> p.current);




                    The usage would be this:



                    Stream<Integer> first10Primes = Prime.stream().limit(10)






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Sep 17 '15 at 15:20









                    vidi

                    670521




                    670521











                    • It would be great to avoid the modulo operation and take advantage of the additive nature of the sieve. Something along the lines of IntStream impossiblePrimes = IntStream.iterate(head * head, i -> i + 2 * head);. But sure, it's more primes-related than head/tail-related.
                      – charlie
                      Jun 28 '16 at 12:20

















                    • It would be great to avoid the modulo operation and take advantage of the additive nature of the sieve. Something along the lines of IntStream impossiblePrimes = IntStream.iterate(head * head, i -> i + 2 * head);. But sure, it's more primes-related than head/tail-related.
                      – charlie
                      Jun 28 '16 at 12:20
















                    It would be great to avoid the modulo operation and take advantage of the additive nature of the sieve. Something along the lines of IntStream impossiblePrimes = IntStream.iterate(head * head, i -> i + 2 * head);. But sure, it's more primes-related than head/tail-related.
                    – charlie
                    Jun 28 '16 at 12:20





                    It would be great to avoid the modulo operation and take advantage of the additive nature of the sieve. Something along the lines of IntStream impossiblePrimes = IntStream.iterate(head * head, i -> i + 2 * head);. But sure, it's more primes-related than head/tail-related.
                    – charlie
                    Jun 28 '16 at 12:20











                    up vote
                    2
                    down vote













                    My StreamEx library has now headTail() operation which solves the problem:



                    public static StreamEx<Integer> sieve(StreamEx<Integer> input) 
                    return input.headTail((head, tail) ->
                    sieve(tail.filter(n -> n % head != 0)).prepend(head));



                    The headTail method takes a BiFunction which will be executed at most once during the stream terminal operation execution. So this implementation is lazy: it does not compute anything until traversal starts and computes only as much prime numbers as requested. The BiFunction receives a first stream element head and the stream of the rest elements tail and can modify the tail in any way it wants. You may use it with predefined input:



                    sieve(IntStreamEx.range(2, 1000).boxed()).forEach(System.out::println);


                    But infinite stream work as well



                    sieve(StreamEx.iterate(2, x -> x+1)).takeWhile(x -> x < 1000)
                    .forEach(System.out::println);
                    // Not the primes till 1000, but 1000 first primes
                    sieve(StreamEx.iterate(2, x -> x+1)).limit(1000).forEach(System.out::println);


                    There's also alternative solution using headTail and predicate concatenation:



                    public static StreamEx<Integer> sieve(StreamEx<Integer> input, IntPredicate isPrime) 
                    return input.headTail((head, tail) -> isPrime.test(head)
                    ? sieve(tail, isPrime.and(n -> n % head != 0)).prepend(head)
                    : sieve(tail, isPrime));


                    sieve(StreamEx.iterate(2, x -> x+1), i -> true).limit(1000).forEach(System.out::println);



                    It interesting to compare recursive solutions: how many primes they capable to generate.



                    @John McClean solution (StreamUtils)



                    John McClean solutions are not lazy: you cannot feed them with infinite stream. So I just found by trial-and-error the maximal allowed upper bound (17793) (after that StackOverflowError occurs):



                    public void sieveTest()
                    sieve(IntStream.range(2, 17793).boxed()).forEach(System.out::println);



                    @John McClean solution (Streamable)



                    public void sieveTest2()
                    sieve(Streamable.range(2, 39990)).forEach(System.out::println);



                    Increasing upper limit above 39990 results in StackOverflowError.



                    @frhack solution (LazySeq)



                    LazySeq<Integer> ints = integers(2);
                    LazySeq primes = sieve(ints); // sieve method from @frhack answer
                    primes.forEach(p -> System.out.println(p));


                    Result: stuck after prime number = 53327 with enormous heap allocation and garbage collection taking more than 90%. It took several minutes to advance from 53323 to 53327, so waiting more seems impractical.



                    @vidi solution



                    Prime.stream().forEach(System.out::println);


                    Result: StackOverflowError after prime number = 134417.



                    My solution (StreamEx)



                    sieve(StreamEx.iterate(2, x -> x+1)).forEach(System.out::println);


                    Result: StackOverflowError after prime number = 236167.



                    @frhack solution (rxjava)



                    Observable<Integer> primes = Observable.from(()->primesStream.iterator());
                    primes.forEach((x) -> System.out.println(x.toString()));


                    Result: StackOverflowError after prime number = 367663.



                    @Holger solution



                    IntStream primes=from(2).filter(i->p.test(i)).peek(i->p=p.and(v->v%i!=0));
                    primes.forEach(System.out::println);


                    Result: StackOverflowError after prime number = 368089.



                    My solution (StreamEx with predicate concatenation)



                    sieve(StreamEx.iterate(2, x -> x+1), i -> true).forEach(System.out::println);


                    Result: StackOverflowError after prime number = 368287.




                    So three solutions involving predicate concatenation win, because each new condition adds only 2 more stack frames. I think, the difference between them is marginal and should not be considered to define a winner. However I like my first StreamEx solution more as it more similar to Scala code.






                    share|improve this answer






















                    • Could you please add timing comparison of respective solutions? Since they all involve predicate contatenation (just more or less explicit) and the modulo operation, they might score equally, though.
                      – charlie
                      Jun 28 '16 at 12:06











                    • Hey man, great work with this library. We use it fairly extensively. The MoreCollectors.flatMapping was really useful, now it is in Java 9. A lot of things you did here could actually be candidates to the main JDK baseline 10+
                      – ailveen
                      Oct 19 '17 at 11:12














                    up vote
                    2
                    down vote













                    My StreamEx library has now headTail() operation which solves the problem:



                    public static StreamEx<Integer> sieve(StreamEx<Integer> input) 
                    return input.headTail((head, tail) ->
                    sieve(tail.filter(n -> n % head != 0)).prepend(head));



                    The headTail method takes a BiFunction which will be executed at most once during the stream terminal operation execution. So this implementation is lazy: it does not compute anything until traversal starts and computes only as much prime numbers as requested. The BiFunction receives a first stream element head and the stream of the rest elements tail and can modify the tail in any way it wants. You may use it with predefined input:



                    sieve(IntStreamEx.range(2, 1000).boxed()).forEach(System.out::println);


                    But infinite stream work as well



                    sieve(StreamEx.iterate(2, x -> x+1)).takeWhile(x -> x < 1000)
                    .forEach(System.out::println);
                    // Not the primes till 1000, but 1000 first primes
                    sieve(StreamEx.iterate(2, x -> x+1)).limit(1000).forEach(System.out::println);


                    There's also alternative solution using headTail and predicate concatenation:



                    public static StreamEx<Integer> sieve(StreamEx<Integer> input, IntPredicate isPrime) 
                    return input.headTail((head, tail) -> isPrime.test(head)
                    ? sieve(tail, isPrime.and(n -> n % head != 0)).prepend(head)
                    : sieve(tail, isPrime));


                    sieve(StreamEx.iterate(2, x -> x+1), i -> true).limit(1000).forEach(System.out::println);



                    It interesting to compare recursive solutions: how many primes they capable to generate.



                    @John McClean solution (StreamUtils)



                    John McClean solutions are not lazy: you cannot feed them with infinite stream. So I just found by trial-and-error the maximal allowed upper bound (17793) (after that StackOverflowError occurs):



                    public void sieveTest()
                    sieve(IntStream.range(2, 17793).boxed()).forEach(System.out::println);



                    @John McClean solution (Streamable)



                    public void sieveTest2()
                    sieve(Streamable.range(2, 39990)).forEach(System.out::println);



                    Increasing upper limit above 39990 results in StackOverflowError.



                    @frhack solution (LazySeq)



                    LazySeq<Integer> ints = integers(2);
                    LazySeq primes = sieve(ints); // sieve method from @frhack answer
                    primes.forEach(p -> System.out.println(p));


                    Result: stuck after prime number = 53327 with enormous heap allocation and garbage collection taking more than 90%. It took several minutes to advance from 53323 to 53327, so waiting more seems impractical.



                    @vidi solution



                    Prime.stream().forEach(System.out::println);


                    Result: StackOverflowError after prime number = 134417.



                    My solution (StreamEx)



                    sieve(StreamEx.iterate(2, x -> x+1)).forEach(System.out::println);


                    Result: StackOverflowError after prime number = 236167.



                    @frhack solution (rxjava)



                    Observable<Integer> primes = Observable.from(()->primesStream.iterator());
                    primes.forEach((x) -> System.out.println(x.toString()));


                    Result: StackOverflowError after prime number = 367663.



                    @Holger solution



                    IntStream primes=from(2).filter(i->p.test(i)).peek(i->p=p.and(v->v%i!=0));
                    primes.forEach(System.out::println);


                    Result: StackOverflowError after prime number = 368089.



                    My solution (StreamEx with predicate concatenation)



                    sieve(StreamEx.iterate(2, x -> x+1), i -> true).forEach(System.out::println);


                    Result: StackOverflowError after prime number = 368287.




                    So three solutions involving predicate concatenation win, because each new condition adds only 2 more stack frames. I think, the difference between them is marginal and should not be considered to define a winner. However I like my first StreamEx solution more as it more similar to Scala code.






                    share|improve this answer






















                    • Could you please add timing comparison of respective solutions? Since they all involve predicate contatenation (just more or less explicit) and the modulo operation, they might score equally, though.
                      – charlie
                      Jun 28 '16 at 12:06











                    • Hey man, great work with this library. We use it fairly extensively. The MoreCollectors.flatMapping was really useful, now it is in Java 9. A lot of things you did here could actually be candidates to the main JDK baseline 10+
                      – ailveen
                      Oct 19 '17 at 11:12












                    up vote
                    2
                    down vote










                    up vote
                    2
                    down vote









                    My StreamEx library has now headTail() operation which solves the problem:



                    public static StreamEx<Integer> sieve(StreamEx<Integer> input) 
                    return input.headTail((head, tail) ->
                    sieve(tail.filter(n -> n % head != 0)).prepend(head));



                    The headTail method takes a BiFunction which will be executed at most once during the stream terminal operation execution. So this implementation is lazy: it does not compute anything until traversal starts and computes only as much prime numbers as requested. The BiFunction receives a first stream element head and the stream of the rest elements tail and can modify the tail in any way it wants. You may use it with predefined input:



                    sieve(IntStreamEx.range(2, 1000).boxed()).forEach(System.out::println);


                    But infinite stream work as well



                    sieve(StreamEx.iterate(2, x -> x+1)).takeWhile(x -> x < 1000)
                    .forEach(System.out::println);
                    // Not the primes till 1000, but 1000 first primes
                    sieve(StreamEx.iterate(2, x -> x+1)).limit(1000).forEach(System.out::println);


                    There's also alternative solution using headTail and predicate concatenation:



                    public static StreamEx<Integer> sieve(StreamEx<Integer> input, IntPredicate isPrime) 
                    return input.headTail((head, tail) -> isPrime.test(head)
                    ? sieve(tail, isPrime.and(n -> n % head != 0)).prepend(head)
                    : sieve(tail, isPrime));


                    sieve(StreamEx.iterate(2, x -> x+1), i -> true).limit(1000).forEach(System.out::println);



                    It interesting to compare recursive solutions: how many primes they capable to generate.



                    @John McClean solution (StreamUtils)



                    John McClean solutions are not lazy: you cannot feed them with infinite stream. So I just found by trial-and-error the maximal allowed upper bound (17793) (after that StackOverflowError occurs):



                    public void sieveTest()
                    sieve(IntStream.range(2, 17793).boxed()).forEach(System.out::println);



                    @John McClean solution (Streamable)



                    public void sieveTest2()
                    sieve(Streamable.range(2, 39990)).forEach(System.out::println);



                    Increasing upper limit above 39990 results in StackOverflowError.



                    @frhack solution (LazySeq)



                    LazySeq<Integer> ints = integers(2);
                    LazySeq primes = sieve(ints); // sieve method from @frhack answer
                    primes.forEach(p -> System.out.println(p));


                    Result: stuck after prime number = 53327 with enormous heap allocation and garbage collection taking more than 90%. It took several minutes to advance from 53323 to 53327, so waiting more seems impractical.



                    @vidi solution



                    Prime.stream().forEach(System.out::println);


                    Result: StackOverflowError after prime number = 134417.



                    My solution (StreamEx)



                    sieve(StreamEx.iterate(2, x -> x+1)).forEach(System.out::println);


                    Result: StackOverflowError after prime number = 236167.



                    @frhack solution (rxjava)



                    Observable<Integer> primes = Observable.from(()->primesStream.iterator());
                    primes.forEach((x) -> System.out.println(x.toString()));


                    Result: StackOverflowError after prime number = 367663.



                    @Holger solution



                    IntStream primes=from(2).filter(i->p.test(i)).peek(i->p=p.and(v->v%i!=0));
                    primes.forEach(System.out::println);


                    Result: StackOverflowError after prime number = 368089.



                    My solution (StreamEx with predicate concatenation)



                    sieve(StreamEx.iterate(2, x -> x+1), i -> true).forEach(System.out::println);


                    Result: StackOverflowError after prime number = 368287.




                    So three solutions involving predicate concatenation win, because each new condition adds only 2 more stack frames. I think, the difference between them is marginal and should not be considered to define a winner. However I like my first StreamEx solution more as it more similar to Scala code.






                    share|improve this answer














                    My StreamEx library has now headTail() operation which solves the problem:



                    public static StreamEx<Integer> sieve(StreamEx<Integer> input) 
                    return input.headTail((head, tail) ->
                    sieve(tail.filter(n -> n % head != 0)).prepend(head));



                    The headTail method takes a BiFunction which will be executed at most once during the stream terminal operation execution. So this implementation is lazy: it does not compute anything until traversal starts and computes only as much prime numbers as requested. The BiFunction receives a first stream element head and the stream of the rest elements tail and can modify the tail in any way it wants. You may use it with predefined input:



                    sieve(IntStreamEx.range(2, 1000).boxed()).forEach(System.out::println);


                    But infinite stream work as well



                    sieve(StreamEx.iterate(2, x -> x+1)).takeWhile(x -> x < 1000)
                    .forEach(System.out::println);
                    // Not the primes till 1000, but 1000 first primes
                    sieve(StreamEx.iterate(2, x -> x+1)).limit(1000).forEach(System.out::println);


                    There's also alternative solution using headTail and predicate concatenation:



                    public static StreamEx<Integer> sieve(StreamEx<Integer> input, IntPredicate isPrime) 
                    return input.headTail((head, tail) -> isPrime.test(head)
                    ? sieve(tail, isPrime.and(n -> n % head != 0)).prepend(head)
                    : sieve(tail, isPrime));


                    sieve(StreamEx.iterate(2, x -> x+1), i -> true).limit(1000).forEach(System.out::println);



                    It interesting to compare recursive solutions: how many primes they capable to generate.



                    @John McClean solution (StreamUtils)



                    John McClean solutions are not lazy: you cannot feed them with infinite stream. So I just found by trial-and-error the maximal allowed upper bound (17793) (after that StackOverflowError occurs):



                    public void sieveTest()
                    sieve(IntStream.range(2, 17793).boxed()).forEach(System.out::println);



                    @John McClean solution (Streamable)



                    public void sieveTest2()
                    sieve(Streamable.range(2, 39990)).forEach(System.out::println);



                    Increasing upper limit above 39990 results in StackOverflowError.



                    @frhack solution (LazySeq)



                    LazySeq<Integer> ints = integers(2);
                    LazySeq primes = sieve(ints); // sieve method from @frhack answer
                    primes.forEach(p -> System.out.println(p));


                    Result: stuck after prime number = 53327 with enormous heap allocation and garbage collection taking more than 90%. It took several minutes to advance from 53323 to 53327, so waiting more seems impractical.



                    @vidi solution



                    Prime.stream().forEach(System.out::println);


                    Result: StackOverflowError after prime number = 134417.



                    My solution (StreamEx)



                    sieve(StreamEx.iterate(2, x -> x+1)).forEach(System.out::println);


                    Result: StackOverflowError after prime number = 236167.



                    @frhack solution (rxjava)



                    Observable<Integer> primes = Observable.from(()->primesStream.iterator());
                    primes.forEach((x) -> System.out.println(x.toString()));


                    Result: StackOverflowError after prime number = 367663.



                    @Holger solution



                    IntStream primes=from(2).filter(i->p.test(i)).peek(i->p=p.and(v->v%i!=0));
                    primes.forEach(System.out::println);


                    Result: StackOverflowError after prime number = 368089.



                    My solution (StreamEx with predicate concatenation)



                    sieve(StreamEx.iterate(2, x -> x+1), i -> true).forEach(System.out::println);


                    Result: StackOverflowError after prime number = 368287.




                    So three solutions involving predicate concatenation win, because each new condition adds only 2 more stack frames. I think, the difference between them is marginal and should not be considered to define a winner. However I like my first StreamEx solution more as it more similar to Scala code.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Oct 4 '16 at 3:40

























                    answered Jan 19 '16 at 10:33









                    Tagir Valeev

                    66.4k10145239




                    66.4k10145239











                    • Could you please add timing comparison of respective solutions? Since they all involve predicate contatenation (just more or less explicit) and the modulo operation, they might score equally, though.
                      – charlie
                      Jun 28 '16 at 12:06











                    • Hey man, great work with this library. We use it fairly extensively. The MoreCollectors.flatMapping was really useful, now it is in Java 9. A lot of things you did here could actually be candidates to the main JDK baseline 10+
                      – ailveen
                      Oct 19 '17 at 11:12
















                    • Could you please add timing comparison of respective solutions? Since they all involve predicate contatenation (just more or less explicit) and the modulo operation, they might score equally, though.
                      – charlie
                      Jun 28 '16 at 12:06











                    • Hey man, great work with this library. We use it fairly extensively. The MoreCollectors.flatMapping was really useful, now it is in Java 9. A lot of things you did here could actually be candidates to the main JDK baseline 10+
                      – ailveen
                      Oct 19 '17 at 11:12















                    Could you please add timing comparison of respective solutions? Since they all involve predicate contatenation (just more or less explicit) and the modulo operation, they might score equally, though.
                    – charlie
                    Jun 28 '16 at 12:06





                    Could you please add timing comparison of respective solutions? Since they all involve predicate contatenation (just more or less explicit) and the modulo operation, they might score equally, though.
                    – charlie
                    Jun 28 '16 at 12:06













                    Hey man, great work with this library. We use it fairly extensively. The MoreCollectors.flatMapping was really useful, now it is in Java 9. A lot of things you did here could actually be candidates to the main JDK baseline 10+
                    – ailveen
                    Oct 19 '17 at 11:12




                    Hey man, great work with this library. We use it fairly extensively. The MoreCollectors.flatMapping was really useful, now it is in Java 9. A lot of things you did here could actually be candidates to the main JDK baseline 10+
                    – ailveen
                    Oct 19 '17 at 11:12










                    up vote
                    1
                    down vote













                    If you don't mind using 3rd party libraries cyclops-streams, I library I wrote has a number of potential solutions.



                    The StreamUtils class has large number of static methods for working directly with java.util.stream.Streams including headAndTail.



                    HeadAndTail<Integer> headAndTail = StreamUtils.headAndTail(Stream.of(1,2,3,4));
                    int head = headAndTail.head(); //1
                    Stream<Integer> tail = headAndTail.tail(); //Stream[2,3,4]


                    The Streamable class represents a replayable Stream and works by building a lazy, caching intermediate data-structure. Because it is caching and repayable - head and tail can be implemented directly and separately.



                    Streamable<Integer> replayable= Streamable.fromStream(Stream.of(1,2,3,4));
                    int head = repayable.head(); //1
                    Stream<Integer> tail = replayable.tail(); //Stream[2,3,4]


                    cyclops-streams also provides a sequential Stream extension that in turn extends jOOλ and has both Tuple based (from jOOλ) and domain object (HeadAndTail) solutions for head and tail extraction.



                    SequenceM.of(1,2,3,4)
                    .splitAtHead(); //Tuple[1,SequenceM[2,3,4]

                    SequenceM.of(1,2,3,4)
                    .headAndTail();


                    Update per Tagir's request -> A Java version of the Scala sieve using SequenceM



                    public void sieveTest()
                    sieve(SequenceM.range(2, 1_000)).forEach(System.out::println);


                    SequenceM<Integer> sieve(SequenceM<Integer> s)

                    return s.headAndTailOptional().map(ht ->SequenceM.of(ht.head())
                    .appendStream(sieve(ht.tail().filter(n -> n % ht.head() != 0))))
                    .orElse(SequenceM.of());



                    And another version via Streamable



                    public void sieveTest2()
                    sieve(Streamable.range(2, 1_000)).forEach(System.out::println);


                    Streamable<Integer> sieve(Streamable<Integer> s)

                    return s.size()==0? Streamable.of() : Streamable.of(s.head())
                    .appendStreamable(sieve(s.tail()
                    .filter(n -> n % s.head() != 0)));



                    Note - neither Streamable of SequenceM have an Empty implementation - hence the size check for Streamable and the use of headAndTailOptional.



                    Finally a version using plain java.util.stream.Stream



                    import static com.aol.cyclops.streams.StreamUtils.headAndTailOptional;

                    public void sieveTest()
                    sieve(IntStream.range(2, 1_000).boxed()).forEach(System.out::println);


                    Stream<Integer> sieve(Stream<Integer> s)

                    return headAndTailOptional(s).map(ht ->Stream.concat(Stream.of(ht.head())
                    ,sieve(ht.tail().filter(n -> n % ht.head() != 0))))
                    .orElse(Stream.of());



                    Another update - a lazy iterative based on @Holger's version using objects rather than primitives (note a primitive version is also possible)



                     final Mutable<Predicate<Integer>> predicate = Mutable.of(x->true);
                    SequenceM.iterate(2, n->n+1)
                    .filter(i->predicate.get().test(i))
                    .peek(i->predicate.mutate(p-> p.and(v -> v%i!=0)))
                    .limit(100000)
                    .forEach(System.out::println);





                    share|improve this answer






















                    • It would be nice to see the full solution of primes problem using your libraries.
                      – Tagir Valeev
                      Jan 11 '16 at 9:45










                    • Teammate going to play around with implementing a sieve of Eratosthenes with Streamable / SequenceM - will keep you posted.
                      – John McClean
                      Jan 11 '16 at 10:43






                    • 1




                      final List<Integer> prime = new ArrayList<>(); SequenceM<Integer> primeNumbers = SequenceM.generate(() -> synchronized (prime) if (prime.isEmpty()) prime.add(2); else int last = prime.get(prime.size() - 1); do int candidate = last; if (!prime.stream().parallel().anyMatch(c -> (candidate) % c == 0)) prime.add(candidate); break; last++; while (true); return prime.get(prime.size() - 1); );
                      – Nikita Sapozhnikov
                      Jan 12 '16 at 11:02











                    • Looks that both solutions are not lazy though. Try sieve(Stream.iterate(2, x -> x+1)).limit(1000) as the source, for example.
                      – Tagir Valeev
                      Jan 19 '16 at 9:14










                    • Yes, the head is evaluated immediately each time, the tail is processed lazily. It's a pretty trivial modification to make the head() method in HeadAndTail evaluate lazily however and one that we will add soon.
                      – John McClean
                      Jan 19 '16 at 11:37














                    up vote
                    1
                    down vote













                    If you don't mind using 3rd party libraries cyclops-streams, I library I wrote has a number of potential solutions.



                    The StreamUtils class has large number of static methods for working directly with java.util.stream.Streams including headAndTail.



                    HeadAndTail<Integer> headAndTail = StreamUtils.headAndTail(Stream.of(1,2,3,4));
                    int head = headAndTail.head(); //1
                    Stream<Integer> tail = headAndTail.tail(); //Stream[2,3,4]


                    The Streamable class represents a replayable Stream and works by building a lazy, caching intermediate data-structure. Because it is caching and repayable - head and tail can be implemented directly and separately.



                    Streamable<Integer> replayable= Streamable.fromStream(Stream.of(1,2,3,4));
                    int head = repayable.head(); //1
                    Stream<Integer> tail = replayable.tail(); //Stream[2,3,4]


                    cyclops-streams also provides a sequential Stream extension that in turn extends jOOλ and has both Tuple based (from jOOλ) and domain object (HeadAndTail) solutions for head and tail extraction.



                    SequenceM.of(1,2,3,4)
                    .splitAtHead(); //Tuple[1,SequenceM[2,3,4]

                    SequenceM.of(1,2,3,4)
                    .headAndTail();


                    Update per Tagir's request -> A Java version of the Scala sieve using SequenceM



                    public void sieveTest()
                    sieve(SequenceM.range(2, 1_000)).forEach(System.out::println);


                    SequenceM<Integer> sieve(SequenceM<Integer> s)

                    return s.headAndTailOptional().map(ht ->SequenceM.of(ht.head())
                    .appendStream(sieve(ht.tail().filter(n -> n % ht.head() != 0))))
                    .orElse(SequenceM.of());



                    And another version via Streamable



                    public void sieveTest2()
                    sieve(Streamable.range(2, 1_000)).forEach(System.out::println);


                    Streamable<Integer> sieve(Streamable<Integer> s)

                    return s.size()==0? Streamable.of() : Streamable.of(s.head())
                    .appendStreamable(sieve(s.tail()
                    .filter(n -> n % s.head() != 0)));



                    Note - neither Streamable of SequenceM have an Empty implementation - hence the size check for Streamable and the use of headAndTailOptional.



                    Finally a version using plain java.util.stream.Stream



                    import static com.aol.cyclops.streams.StreamUtils.headAndTailOptional;

                    public void sieveTest()
                    sieve(IntStream.range(2, 1_000).boxed()).forEach(System.out::println);


                    Stream<Integer> sieve(Stream<Integer> s)

                    return headAndTailOptional(s).map(ht ->Stream.concat(Stream.of(ht.head())
                    ,sieve(ht.tail().filter(n -> n % ht.head() != 0))))
                    .orElse(Stream.of());



                    Another update - a lazy iterative based on @Holger's version using objects rather than primitives (note a primitive version is also possible)



                     final Mutable<Predicate<Integer>> predicate = Mutable.of(x->true);
                    SequenceM.iterate(2, n->n+1)
                    .filter(i->predicate.get().test(i))
                    .peek(i->predicate.mutate(p-> p.and(v -> v%i!=0)))
                    .limit(100000)
                    .forEach(System.out::println);





                    share|improve this answer






















                    • It would be nice to see the full solution of primes problem using your libraries.
                      – Tagir Valeev
                      Jan 11 '16 at 9:45










                    • Teammate going to play around with implementing a sieve of Eratosthenes with Streamable / SequenceM - will keep you posted.
                      – John McClean
                      Jan 11 '16 at 10:43






                    • 1




                      final List<Integer> prime = new ArrayList<>(); SequenceM<Integer> primeNumbers = SequenceM.generate(() -> synchronized (prime) if (prime.isEmpty()) prime.add(2); else int last = prime.get(prime.size() - 1); do int candidate = last; if (!prime.stream().parallel().anyMatch(c -> (candidate) % c == 0)) prime.add(candidate); break; last++; while (true); return prime.get(prime.size() - 1); );
                      – Nikita Sapozhnikov
                      Jan 12 '16 at 11:02











                    • Looks that both solutions are not lazy though. Try sieve(Stream.iterate(2, x -> x+1)).limit(1000) as the source, for example.
                      – Tagir Valeev
                      Jan 19 '16 at 9:14










                    • Yes, the head is evaluated immediately each time, the tail is processed lazily. It's a pretty trivial modification to make the head() method in HeadAndTail evaluate lazily however and one that we will add soon.
                      – John McClean
                      Jan 19 '16 at 11:37












                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    If you don't mind using 3rd party libraries cyclops-streams, I library I wrote has a number of potential solutions.



                    The StreamUtils class has large number of static methods for working directly with java.util.stream.Streams including headAndTail.



                    HeadAndTail<Integer> headAndTail = StreamUtils.headAndTail(Stream.of(1,2,3,4));
                    int head = headAndTail.head(); //1
                    Stream<Integer> tail = headAndTail.tail(); //Stream[2,3,4]


                    The Streamable class represents a replayable Stream and works by building a lazy, caching intermediate data-structure. Because it is caching and repayable - head and tail can be implemented directly and separately.



                    Streamable<Integer> replayable= Streamable.fromStream(Stream.of(1,2,3,4));
                    int head = repayable.head(); //1
                    Stream<Integer> tail = replayable.tail(); //Stream[2,3,4]


                    cyclops-streams also provides a sequential Stream extension that in turn extends jOOλ and has both Tuple based (from jOOλ) and domain object (HeadAndTail) solutions for head and tail extraction.



                    SequenceM.of(1,2,3,4)
                    .splitAtHead(); //Tuple[1,SequenceM[2,3,4]

                    SequenceM.of(1,2,3,4)
                    .headAndTail();


                    Update per Tagir's request -> A Java version of the Scala sieve using SequenceM



                    public void sieveTest()
                    sieve(SequenceM.range(2, 1_000)).forEach(System.out::println);


                    SequenceM<Integer> sieve(SequenceM<Integer> s)

                    return s.headAndTailOptional().map(ht ->SequenceM.of(ht.head())
                    .appendStream(sieve(ht.tail().filter(n -> n % ht.head() != 0))))
                    .orElse(SequenceM.of());



                    And another version via Streamable



                    public void sieveTest2()
                    sieve(Streamable.range(2, 1_000)).forEach(System.out::println);


                    Streamable<Integer> sieve(Streamable<Integer> s)

                    return s.size()==0? Streamable.of() : Streamable.of(s.head())
                    .appendStreamable(sieve(s.tail()
                    .filter(n -> n % s.head() != 0)));



                    Note - neither Streamable of SequenceM have an Empty implementation - hence the size check for Streamable and the use of headAndTailOptional.



                    Finally a version using plain java.util.stream.Stream



                    import static com.aol.cyclops.streams.StreamUtils.headAndTailOptional;

                    public void sieveTest()
                    sieve(IntStream.range(2, 1_000).boxed()).forEach(System.out::println);


                    Stream<Integer> sieve(Stream<Integer> s)

                    return headAndTailOptional(s).map(ht ->Stream.concat(Stream.of(ht.head())
                    ,sieve(ht.tail().filter(n -> n % ht.head() != 0))))
                    .orElse(Stream.of());



                    Another update - a lazy iterative based on @Holger's version using objects rather than primitives (note a primitive version is also possible)



                     final Mutable<Predicate<Integer>> predicate = Mutable.of(x->true);
                    SequenceM.iterate(2, n->n+1)
                    .filter(i->predicate.get().test(i))
                    .peek(i->predicate.mutate(p-> p.and(v -> v%i!=0)))
                    .limit(100000)
                    .forEach(System.out::println);





                    share|improve this answer














                    If you don't mind using 3rd party libraries cyclops-streams, I library I wrote has a number of potential solutions.



                    The StreamUtils class has large number of static methods for working directly with java.util.stream.Streams including headAndTail.



                    HeadAndTail<Integer> headAndTail = StreamUtils.headAndTail(Stream.of(1,2,3,4));
                    int head = headAndTail.head(); //1
                    Stream<Integer> tail = headAndTail.tail(); //Stream[2,3,4]


                    The Streamable class represents a replayable Stream and works by building a lazy, caching intermediate data-structure. Because it is caching and repayable - head and tail can be implemented directly and separately.



                    Streamable<Integer> replayable= Streamable.fromStream(Stream.of(1,2,3,4));
                    int head = repayable.head(); //1
                    Stream<Integer> tail = replayable.tail(); //Stream[2,3,4]


                    cyclops-streams also provides a sequential Stream extension that in turn extends jOOλ and has both Tuple based (from jOOλ) and domain object (HeadAndTail) solutions for head and tail extraction.



                    SequenceM.of(1,2,3,4)
                    .splitAtHead(); //Tuple[1,SequenceM[2,3,4]

                    SequenceM.of(1,2,3,4)
                    .headAndTail();


                    Update per Tagir's request -> A Java version of the Scala sieve using SequenceM



                    public void sieveTest()
                    sieve(SequenceM.range(2, 1_000)).forEach(System.out::println);


                    SequenceM<Integer> sieve(SequenceM<Integer> s)

                    return s.headAndTailOptional().map(ht ->SequenceM.of(ht.head())
                    .appendStream(sieve(ht.tail().filter(n -> n % ht.head() != 0))))
                    .orElse(SequenceM.of());



                    And another version via Streamable



                    public void sieveTest2()
                    sieve(Streamable.range(2, 1_000)).forEach(System.out::println);


                    Streamable<Integer> sieve(Streamable<Integer> s)

                    return s.size()==0? Streamable.of() : Streamable.of(s.head())
                    .appendStreamable(sieve(s.tail()
                    .filter(n -> n % s.head() != 0)));



                    Note - neither Streamable of SequenceM have an Empty implementation - hence the size check for Streamable and the use of headAndTailOptional.



                    Finally a version using plain java.util.stream.Stream



                    import static com.aol.cyclops.streams.StreamUtils.headAndTailOptional;

                    public void sieveTest()
                    sieve(IntStream.range(2, 1_000).boxed()).forEach(System.out::println);


                    Stream<Integer> sieve(Stream<Integer> s)

                    return headAndTailOptional(s).map(ht ->Stream.concat(Stream.of(ht.head())
                    ,sieve(ht.tail().filter(n -> n % ht.head() != 0))))
                    .orElse(Stream.of());



                    Another update - a lazy iterative based on @Holger's version using objects rather than primitives (note a primitive version is also possible)



                     final Mutable<Predicate<Integer>> predicate = Mutable.of(x->true);
                    SequenceM.iterate(2, n->n+1)
                    .filter(i->predicate.get().test(i))
                    .peek(i->predicate.mutate(p-> p.and(v -> v%i!=0)))
                    .limit(100000)
                    .forEach(System.out::println);






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jan 19 '16 at 14:11

























                    answered Jan 11 '16 at 6:00









                    John McClean

                    3,6491424




                    3,6491424











                    • It would be nice to see the full solution of primes problem using your libraries.
                      – Tagir Valeev
                      Jan 11 '16 at 9:45










                    • Teammate going to play around with implementing a sieve of Eratosthenes with Streamable / SequenceM - will keep you posted.
                      – John McClean
                      Jan 11 '16 at 10:43






                    • 1




                      final List<Integer> prime = new ArrayList<>(); SequenceM<Integer> primeNumbers = SequenceM.generate(() -> synchronized (prime) if (prime.isEmpty()) prime.add(2); else int last = prime.get(prime.size() - 1); do int candidate = last; if (!prime.stream().parallel().anyMatch(c -> (candidate) % c == 0)) prime.add(candidate); break; last++; while (true); return prime.get(prime.size() - 1); );
                      – Nikita Sapozhnikov
                      Jan 12 '16 at 11:02











                    • Looks that both solutions are not lazy though. Try sieve(Stream.iterate(2, x -> x+1)).limit(1000) as the source, for example.
                      – Tagir Valeev
                      Jan 19 '16 at 9:14










                    • Yes, the head is evaluated immediately each time, the tail is processed lazily. It's a pretty trivial modification to make the head() method in HeadAndTail evaluate lazily however and one that we will add soon.
                      – John McClean
                      Jan 19 '16 at 11:37
















                    • It would be nice to see the full solution of primes problem using your libraries.
                      – Tagir Valeev
                      Jan 11 '16 at 9:45










                    • Teammate going to play around with implementing a sieve of Eratosthenes with Streamable / SequenceM - will keep you posted.
                      – John McClean
                      Jan 11 '16 at 10:43






                    • 1




                      final List<Integer> prime = new ArrayList<>(); SequenceM<Integer> primeNumbers = SequenceM.generate(() -> synchronized (prime) if (prime.isEmpty()) prime.add(2); else int last = prime.get(prime.size() - 1); do int candidate = last; if (!prime.stream().parallel().anyMatch(c -> (candidate) % c == 0)) prime.add(candidate); break; last++; while (true); return prime.get(prime.size() - 1); );
                      – Nikita Sapozhnikov
                      Jan 12 '16 at 11:02











                    • Looks that both solutions are not lazy though. Try sieve(Stream.iterate(2, x -> x+1)).limit(1000) as the source, for example.
                      – Tagir Valeev
                      Jan 19 '16 at 9:14










                    • Yes, the head is evaluated immediately each time, the tail is processed lazily. It's a pretty trivial modification to make the head() method in HeadAndTail evaluate lazily however and one that we will add soon.
                      – John McClean
                      Jan 19 '16 at 11:37















                    It would be nice to see the full solution of primes problem using your libraries.
                    – Tagir Valeev
                    Jan 11 '16 at 9:45




                    It would be nice to see the full solution of primes problem using your libraries.
                    – Tagir Valeev
                    Jan 11 '16 at 9:45












                    Teammate going to play around with implementing a sieve of Eratosthenes with Streamable / SequenceM - will keep you posted.
                    – John McClean
                    Jan 11 '16 at 10:43




                    Teammate going to play around with implementing a sieve of Eratosthenes with Streamable / SequenceM - will keep you posted.
                    – John McClean
                    Jan 11 '16 at 10:43




                    1




                    1




                    final List<Integer> prime = new ArrayList<>(); SequenceM<Integer> primeNumbers = SequenceM.generate(() -> synchronized (prime) if (prime.isEmpty()) prime.add(2); else int last = prime.get(prime.size() - 1); do int candidate = last; if (!prime.stream().parallel().anyMatch(c -> (candidate) % c == 0)) prime.add(candidate); break; last++; while (true); return prime.get(prime.size() - 1); );
                    – Nikita Sapozhnikov
                    Jan 12 '16 at 11:02





                    final List<Integer> prime = new ArrayList<>(); SequenceM<Integer> primeNumbers = SequenceM.generate(() -> synchronized (prime) if (prime.isEmpty()) prime.add(2); else int last = prime.get(prime.size() - 1); do int candidate = last; if (!prime.stream().parallel().anyMatch(c -> (candidate) % c == 0)) prime.add(candidate); break; last++; while (true); return prime.get(prime.size() - 1); );
                    – Nikita Sapozhnikov
                    Jan 12 '16 at 11:02













                    Looks that both solutions are not lazy though. Try sieve(Stream.iterate(2, x -> x+1)).limit(1000) as the source, for example.
                    – Tagir Valeev
                    Jan 19 '16 at 9:14




                    Looks that both solutions are not lazy though. Try sieve(Stream.iterate(2, x -> x+1)).limit(1000) as the source, for example.
                    – Tagir Valeev
                    Jan 19 '16 at 9:14












                    Yes, the head is evaluated immediately each time, the tail is processed lazily. It's a pretty trivial modification to make the head() method in HeadAndTail evaluate lazily however and one that we will add soon.
                    – John McClean
                    Jan 19 '16 at 11:37




                    Yes, the head is evaluated immediately each time, the tail is processed lazily. It's a pretty trivial modification to make the head() method in HeadAndTail evaluate lazily however and one that we will add soon.
                    – John McClean
                    Jan 19 '16 at 11:37










                    up vote
                    0
                    down vote













                    To get head and tail you need a Lazy Stream implementation. Java 8 stream or RxJava are not suitable.



                    You can use for example LazySeq as follows.




                    Lazy sequence is always traversed from the beginning using very cheap
                    first/rest decomposition (head() and tail())



                    LazySeq implements java.util.List interface, thus can be used in
                    variety of places. Moreover it also implements Java 8 enhancements to
                    collections, namely streams and collectors





                    package com.company;

                    import com.nurkiewicz.lazyseq.LazySeq;

                    public class Main

                    public static void main(String args)

                    LazySeq<Integer> ints = integers(2);
                    LazySeq primes = sieve(ints);
                    primes.take(10).forEach(p -> System.out.println(p));



                    private static LazySeq<Integer> sieve(LazySeq<Integer> s)
                    return LazySeq.cons(s.head(), () -> sieve(s.filter(x -> x % s.head() != 0)));


                    private static LazySeq<Integer> integers(int from)
                    return LazySeq.cons(from, () -> integers(from + 1));








                    share|improve this answer


























                      up vote
                      0
                      down vote













                      To get head and tail you need a Lazy Stream implementation. Java 8 stream or RxJava are not suitable.



                      You can use for example LazySeq as follows.




                      Lazy sequence is always traversed from the beginning using very cheap
                      first/rest decomposition (head() and tail())



                      LazySeq implements java.util.List interface, thus can be used in
                      variety of places. Moreover it also implements Java 8 enhancements to
                      collections, namely streams and collectors





                      package com.company;

                      import com.nurkiewicz.lazyseq.LazySeq;

                      public class Main

                      public static void main(String args)

                      LazySeq<Integer> ints = integers(2);
                      LazySeq primes = sieve(ints);
                      primes.take(10).forEach(p -> System.out.println(p));



                      private static LazySeq<Integer> sieve(LazySeq<Integer> s)
                      return LazySeq.cons(s.head(), () -> sieve(s.filter(x -> x % s.head() != 0)));


                      private static LazySeq<Integer> integers(int from)
                      return LazySeq.cons(from, () -> integers(from + 1));








                      share|improve this answer
























                        up vote
                        0
                        down vote










                        up vote
                        0
                        down vote









                        To get head and tail you need a Lazy Stream implementation. Java 8 stream or RxJava are not suitable.



                        You can use for example LazySeq as follows.




                        Lazy sequence is always traversed from the beginning using very cheap
                        first/rest decomposition (head() and tail())



                        LazySeq implements java.util.List interface, thus can be used in
                        variety of places. Moreover it also implements Java 8 enhancements to
                        collections, namely streams and collectors





                        package com.company;

                        import com.nurkiewicz.lazyseq.LazySeq;

                        public class Main

                        public static void main(String args)

                        LazySeq<Integer> ints = integers(2);
                        LazySeq primes = sieve(ints);
                        primes.take(10).forEach(p -> System.out.println(p));



                        private static LazySeq<Integer> sieve(LazySeq<Integer> s)
                        return LazySeq.cons(s.head(), () -> sieve(s.filter(x -> x % s.head() != 0)));


                        private static LazySeq<Integer> integers(int from)
                        return LazySeq.cons(from, () -> integers(from + 1));








                        share|improve this answer














                        To get head and tail you need a Lazy Stream implementation. Java 8 stream or RxJava are not suitable.



                        You can use for example LazySeq as follows.




                        Lazy sequence is always traversed from the beginning using very cheap
                        first/rest decomposition (head() and tail())



                        LazySeq implements java.util.List interface, thus can be used in
                        variety of places. Moreover it also implements Java 8 enhancements to
                        collections, namely streams and collectors





                        package com.company;

                        import com.nurkiewicz.lazyseq.LazySeq;

                        public class Main

                        public static void main(String args)

                        LazySeq<Integer> ints = integers(2);
                        LazySeq primes = sieve(ints);
                        primes.take(10).forEach(p -> System.out.println(p));



                        private static LazySeq<Integer> sieve(LazySeq<Integer> s)
                        return LazySeq.cons(s.head(), () -> sieve(s.filter(x -> x % s.head() != 0)));


                        private static LazySeq<Integer> integers(int from)
                        return LazySeq.cons(from, () -> integers(from + 1));









                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited Jun 6 '15 at 11:08

























                        answered Jun 6 '15 at 10:23









                        frhack

                        2,5861820




                        2,5861820




















                            up vote
                            0
                            down vote













                            Here is another recipe using the way suggested by Holger.
                            It use RxJava just to add the possibility to use the take(int) method and many others.



                            package com.company;

                            import rx.Observable;

                            import java.util.function.IntPredicate;
                            import java.util.stream.IntStream;

                            public class Main

                            public static void main(String args)

                            final IntPredicate p=(x)->true;
                            IntStream primesStream=IntStream.iterate(2,n->n+1).filter(i -> p[0].test(i)).peek(i->p[0]=p[0].and(v->v%i!=0) );

                            Observable primes = Observable.from(()->primesStream.iterator());

                            primes.take(10).forEach((x) -> System.out.println(x.toString()));










                            share|improve this answer
























                              up vote
                              0
                              down vote













                              Here is another recipe using the way suggested by Holger.
                              It use RxJava just to add the possibility to use the take(int) method and many others.



                              package com.company;

                              import rx.Observable;

                              import java.util.function.IntPredicate;
                              import java.util.stream.IntStream;

                              public class Main

                              public static void main(String args)

                              final IntPredicate p=(x)->true;
                              IntStream primesStream=IntStream.iterate(2,n->n+1).filter(i -> p[0].test(i)).peek(i->p[0]=p[0].and(v->v%i!=0) );

                              Observable primes = Observable.from(()->primesStream.iterator());

                              primes.take(10).forEach((x) -> System.out.println(x.toString()));










                              share|improve this answer






















                                up vote
                                0
                                down vote










                                up vote
                                0
                                down vote









                                Here is another recipe using the way suggested by Holger.
                                It use RxJava just to add the possibility to use the take(int) method and many others.



                                package com.company;

                                import rx.Observable;

                                import java.util.function.IntPredicate;
                                import java.util.stream.IntStream;

                                public class Main

                                public static void main(String args)

                                final IntPredicate p=(x)->true;
                                IntStream primesStream=IntStream.iterate(2,n->n+1).filter(i -> p[0].test(i)).peek(i->p[0]=p[0].and(v->v%i!=0) );

                                Observable primes = Observable.from(()->primesStream.iterator());

                                primes.take(10).forEach((x) -> System.out.println(x.toString()));










                                share|improve this answer












                                Here is another recipe using the way suggested by Holger.
                                It use RxJava just to add the possibility to use the take(int) method and many others.



                                package com.company;

                                import rx.Observable;

                                import java.util.function.IntPredicate;
                                import java.util.stream.IntStream;

                                public class Main

                                public static void main(String args)

                                final IntPredicate p=(x)->true;
                                IntStream primesStream=IntStream.iterate(2,n->n+1).filter(i -> p[0].test(i)).peek(i->p[0]=p[0].and(v->v%i!=0) );

                                Observable primes = Observable.from(()->primesStream.iterator());

                                primes.take(10).forEach((x) -> System.out.println(x.toString()));











                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Jun 6 '15 at 11:11









                                frhack

                                2,5861820




                                2,5861820




















                                    up vote
                                    0
                                    down vote













                                    There are many interesting suggestions provided here, but if someone needs a solution without dependencies to third party libraries I came up with this:



                                     import java.util.AbstractMap;
                                    import java.util.Optional;
                                    import java.util.Spliterators;
                                    import java.util.stream.StreamSupport;

                                    /**
                                    * Splits a stream in the head element and a tail stream.
                                    * Parallel streams are not supported.
                                    *
                                    * @param stream Stream to split.
                                    * @param <T> Type of the input stream.
                                    * @return A map entry where @link Map.Entry#getKey() contains an
                                    * optional with the first element (head) of the original stream
                                    * and @link Map.Entry#getValue() the tail of the original stream.
                                    * @throws IllegalArgumentException for parallel streams.
                                    */
                                    public static <T> Map.Entry<Optional<T>, Stream<T>> headAndTail(final Stream<T> stream)
                                    if (stream.isParallel())
                                    throw new IllegalArgumentException("parallel streams are not supported");

                                    final Iterator<T> iterator = stream.iterator();
                                    return new AbstractMap.SimpleImmutableEntry<>(
                                    iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty(),
                                    StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false)
                                    );






                                    share|improve this answer
























                                      up vote
                                      0
                                      down vote













                                      There are many interesting suggestions provided here, but if someone needs a solution without dependencies to third party libraries I came up with this:



                                       import java.util.AbstractMap;
                                      import java.util.Optional;
                                      import java.util.Spliterators;
                                      import java.util.stream.StreamSupport;

                                      /**
                                      * Splits a stream in the head element and a tail stream.
                                      * Parallel streams are not supported.
                                      *
                                      * @param stream Stream to split.
                                      * @param <T> Type of the input stream.
                                      * @return A map entry where @link Map.Entry#getKey() contains an
                                      * optional with the first element (head) of the original stream
                                      * and @link Map.Entry#getValue() the tail of the original stream.
                                      * @throws IllegalArgumentException for parallel streams.
                                      */
                                      public static <T> Map.Entry<Optional<T>, Stream<T>> headAndTail(final Stream<T> stream)
                                      if (stream.isParallel())
                                      throw new IllegalArgumentException("parallel streams are not supported");

                                      final Iterator<T> iterator = stream.iterator();
                                      return new AbstractMap.SimpleImmutableEntry<>(
                                      iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty(),
                                      StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false)
                                      );






                                      share|improve this answer






















                                        up vote
                                        0
                                        down vote










                                        up vote
                                        0
                                        down vote









                                        There are many interesting suggestions provided here, but if someone needs a solution without dependencies to third party libraries I came up with this:



                                         import java.util.AbstractMap;
                                        import java.util.Optional;
                                        import java.util.Spliterators;
                                        import java.util.stream.StreamSupport;

                                        /**
                                        * Splits a stream in the head element and a tail stream.
                                        * Parallel streams are not supported.
                                        *
                                        * @param stream Stream to split.
                                        * @param <T> Type of the input stream.
                                        * @return A map entry where @link Map.Entry#getKey() contains an
                                        * optional with the first element (head) of the original stream
                                        * and @link Map.Entry#getValue() the tail of the original stream.
                                        * @throws IllegalArgumentException for parallel streams.
                                        */
                                        public static <T> Map.Entry<Optional<T>, Stream<T>> headAndTail(final Stream<T> stream)
                                        if (stream.isParallel())
                                        throw new IllegalArgumentException("parallel streams are not supported");

                                        final Iterator<T> iterator = stream.iterator();
                                        return new AbstractMap.SimpleImmutableEntry<>(
                                        iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty(),
                                        StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false)
                                        );






                                        share|improve this answer












                                        There are many interesting suggestions provided here, but if someone needs a solution without dependencies to third party libraries I came up with this:



                                         import java.util.AbstractMap;
                                        import java.util.Optional;
                                        import java.util.Spliterators;
                                        import java.util.stream.StreamSupport;

                                        /**
                                        * Splits a stream in the head element and a tail stream.
                                        * Parallel streams are not supported.
                                        *
                                        * @param stream Stream to split.
                                        * @param <T> Type of the input stream.
                                        * @return A map entry where @link Map.Entry#getKey() contains an
                                        * optional with the first element (head) of the original stream
                                        * and @link Map.Entry#getValue() the tail of the original stream.
                                        * @throws IllegalArgumentException for parallel streams.
                                        */
                                        public static <T> Map.Entry<Optional<T>, Stream<T>> headAndTail(final Stream<T> stream)
                                        if (stream.isParallel())
                                        throw new IllegalArgumentException("parallel streams are not supported");

                                        final Iterator<T> iterator = stream.iterator();
                                        return new AbstractMap.SimpleImmutableEntry<>(
                                        iterator.hasNext() ? Optional.of(iterator.next()) : Optional.empty(),
                                        StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false)
                                        );







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Nov 11 at 12:22









                                        Peter

                                        678610




                                        678610




















                                            up vote
                                            -1
                                            down vote













                                            If you want to get head of a stream, just:



                                            IntStream.range(1, 5).first();


                                            If you want to get tail of a stream, just:



                                            IntStream.range(1, 5).skip(1);


                                            If you want to get both head and tail of a stream, just:



                                            IntStream s = IntStream.range(1, 5);
                                            int head = s.head();
                                            IntStream tail = s.tail();


                                            If you want to find the prime, just:



                                            LongStream.range(2, n)
                                            .filter(i -> LongStream.range(2, (long) Math.sqrt(i) + 1).noneMatch(j -> i % j == 0))
                                            .forEach(N::println);


                                            If you want to know more, go to get AbacusUtil



                                            Declaration: I'm the developer of AbacusUtil.






                                            share|improve this answer


























                                              up vote
                                              -1
                                              down vote













                                              If you want to get head of a stream, just:



                                              IntStream.range(1, 5).first();


                                              If you want to get tail of a stream, just:



                                              IntStream.range(1, 5).skip(1);


                                              If you want to get both head and tail of a stream, just:



                                              IntStream s = IntStream.range(1, 5);
                                              int head = s.head();
                                              IntStream tail = s.tail();


                                              If you want to find the prime, just:



                                              LongStream.range(2, n)
                                              .filter(i -> LongStream.range(2, (long) Math.sqrt(i) + 1).noneMatch(j -> i % j == 0))
                                              .forEach(N::println);


                                              If you want to know more, go to get AbacusUtil



                                              Declaration: I'm the developer of AbacusUtil.






                                              share|improve this answer
























                                                up vote
                                                -1
                                                down vote










                                                up vote
                                                -1
                                                down vote









                                                If you want to get head of a stream, just:



                                                IntStream.range(1, 5).first();


                                                If you want to get tail of a stream, just:



                                                IntStream.range(1, 5).skip(1);


                                                If you want to get both head and tail of a stream, just:



                                                IntStream s = IntStream.range(1, 5);
                                                int head = s.head();
                                                IntStream tail = s.tail();


                                                If you want to find the prime, just:



                                                LongStream.range(2, n)
                                                .filter(i -> LongStream.range(2, (long) Math.sqrt(i) + 1).noneMatch(j -> i % j == 0))
                                                .forEach(N::println);


                                                If you want to know more, go to get AbacusUtil



                                                Declaration: I'm the developer of AbacusUtil.






                                                share|improve this answer














                                                If you want to get head of a stream, just:



                                                IntStream.range(1, 5).first();


                                                If you want to get tail of a stream, just:



                                                IntStream.range(1, 5).skip(1);


                                                If you want to get both head and tail of a stream, just:



                                                IntStream s = IntStream.range(1, 5);
                                                int head = s.head();
                                                IntStream tail = s.tail();


                                                If you want to find the prime, just:



                                                LongStream.range(2, n)
                                                .filter(i -> LongStream.range(2, (long) Math.sqrt(i) + 1).noneMatch(j -> i % j == 0))
                                                .forEach(N::println);


                                                If you want to know more, go to get AbacusUtil



                                                Declaration: I'm the developer of AbacusUtil.







                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Jan 7 '17 at 21:09

























                                                answered Dec 1 '16 at 19:43









                                                user_3380739

                                                88868




                                                88868



























                                                    draft saved

                                                    draft discarded
















































                                                    Thanks for contributing an answer to Stack Overflow!


                                                    • Please be sure to answer the question. Provide details and share your research!

                                                    But avoid


                                                    • Asking for help, clarification, or responding to other answers.

                                                    • Making statements based on opinion; back them up with references or personal experience.

                                                    To learn more, see our tips on writing great answers.





                                                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                                    Please pay close attention to the following guidance:


                                                    • Please be sure to answer the question. Provide details and share your research!

                                                    But avoid


                                                    • Asking for help, clarification, or responding to other answers.

                                                    • Making statements based on opinion; back them up with references or personal experience.

                                                    To learn more, see our tips on writing great answers.




                                                    draft saved


                                                    draft discarded














                                                    StackExchange.ready(
                                                    function ()
                                                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f19803058%2fjava-8-stream-getting-head-and-tail%23new-answer', 'question_page');

                                                    );

                                                    Post as a guest















                                                    Required, but never shown





















































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown

































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown







                                                    Popular posts from this blog

                                                    Top Tejano songwriter Luis Silva dead of heart attack at 64

                                                    政党

                                                    天津地下鉄3号線