Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an infinite stream with Java 8

Tags:

java

java-8

Is there a easy way to create a infinity stream using java-8 without external libraries?

For example in Scala:

Iterator.iterate(0)(_ + 2)
like image 279
sndyuk Avatar asked Mar 18 '14 15:03

sndyuk


People also ask

How we can create an infinite stream in Java 8?

We created an infinite stream using an iterate() method. Then we called a limit() transformation and a collect() terminal operation. Then in our resulting List, we will have first 10 elements of an infinite sequence due to a laziness of a Stream.

Can Java stream be infinite size?

Note that there are built-in infinite streams such as java. util. Random. ints() which gives you an infinite stream of random integers.

Which method of the stream class can be used to create infinite streams?

iterate() and Stream. generate() methods can be used to produce infinite streams.


3 Answers

Yes, there is an easy way:

IntStream.iterate(0, i -> i + 2);

With as usecase:

IntStream.iterate(0, i -> i + 2)
         .limit(100)
         .forEach(System.out::println);

Which prints out 0 to 198 increasing in steps of 2.

The generic method is:

Stream.iterate(T seed, UnaryOperator<T> f);

The latter may be more uncommon in usage.

like image 66
skiwi Avatar answered Oct 10 '22 09:10

skiwi


Here is an example:

PrimitiveIterator.OfInt it = new PrimitiveIterator.OfInt() {
    private int value = 0;

    @Override
    public int nextInt() {
        return value++;
    }

    @Override
    public boolean hasNext() {
        return true;
    }
};

Spliterator.OfInt spliterator = Spliterators.spliteratorUnknownSize(it,
    Spliterator.DISTINCT | Spliterator.IMMUTABLE |
    Spliterator.ORDERED | Spliterator.SORTED);

IntStream stream = StreamSupport.intStream(spliterator, false);

It's a bit verbose, as you see. To print the first 10 elements of this stream:

stream.limit(10).forEach(System.out::println);

You can ofcourse also transform the elements, like you do in your Scala example:

IntStream plusTwoStream = stream.map(n -> n + 2);

Note that there are built-in infinite streams such as java.util.Random.ints() which gives you an infinite stream of random integers.

like image 7
Jesper Avatar answered Oct 10 '22 08:10

Jesper


There is another possible solution in Java 8:

AtomicInteger adder = new AtomicInteger();
IntStream stream = IntStream.generate(() -> adder.getAndAdd(2));

Important: an order of numbers is preserved only if the stream is sequential.


It's also worth noting that a new version of the IntStream.iterate has been added since Java 9:

static IntStream iterate​(int seed,
                         IntPredicate hasNext,
                         IntUnaryOperator next);
  • seed - the initial element;
  • hasNext - a predicate to apply to elements to determine when the stream must terminate;
  • next - a function to be applied to the previous element to produce a new element.

Examples:

IntStream stream = IntStream.iterate(0, i -> i >= 0, i -> i + 2);

IntStream.iterate(0, i -> i < 10, i -> i + 2).forEach(System.out::println);
like image 4
Oleksandr Pyrohov Avatar answered Oct 10 '22 08:10

Oleksandr Pyrohov