How to create an infinite stream with Java 8
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.
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.
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);