How to create an infinite Stream<E> out of an Iterator<E>?
iterator, java, java-8, java-stream
Solution
Your mistake is to think that you need an `Iterator` or a `Collection` to create a `Stream`. For creating an infinite stream, a single method providing one value after another is enough. So for your class `FibonacciSupplier` the simplest use is:
IntStream s=IntStream.generate(FibonacciSupplier.infinite()::next);
or, if you prefer boxed values:
Stream<Integer> s=Stream.generate(FibonacciSupplier.infinite()::next);
Note that in this case the method does not have to be named `next` nor fulfill the `Iterator` interface. But it doesn’t matter if it does as with your class. Further, as we just told the stream to use the `next` method as a `Supplier`, the `hasNext` method will never be called. It’s just infinite.
Creating a finite stream using your `Iterator` is a bit more complicated:
Stream<Integer> s=StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
FibonacciSupplier.finite(intPredicate), Spliterator.ORDERED),
false);
In this case if you want a finite `IntStream` with unboxed `int` values your `FibonacciSupplier` should implement `PrimitiveIterator.OfInt`.
Problem
Looking at the following class I've made: ``` public class FibonacciSupplier implements Iterator<Integer> { private final IntPredicate hasNextPredicate; private int beforePrevious = 0; private int previous = 1; private FibonacciSupplier(final IntPredicate hasNextPredicate) { this.hasNextPredicate = hasNextPredicate; } @Override public boolean hasNext() { return hasNextPredicate.test(previous); } @Override public Integer next() { int result = beforePrevious + previous; beforePrevious = previous; previous = result; return result; } public static FibonacciSupplier infinite() { return new FibonacciSupplier(i -> true); } public static FibonacciSupplier finite(final IntPredicate predicate) { return new FibonacciSupplier(predicate); } } ``` And the usage of it in: ``` public class Problem2 extends Problem<Integer> { @Override public void run() { result = toList(FibonacciSupplier.finite(i -> (i <= 4_000_000))) .stream() .filter(i -> (i % 2 == 0)) .mapToInt(i -> i) .sum(); } @Override public String getName() { return "Problem 2"; } private static <E> List<E> toList(final Iterator<E> iterator) { List<E> list = new ArrayList<>(); while (iterator.hasNext()) { list.add(iterator.next()); } return list; } } ``` How would I be able to create an infinite `Stream<E>`? If I were to use `Stream<Integer> infiniteStream = toList(FibonacciSupplier.infinite()).stream()`, I would, possibly surprisingly, never get an infinite stream. Instead the code would loop forever in the creation of the `list` in an underlying method. This so far is purely theoretical, but I can definately understand the need for it if I would want to first skip the first x numbers from an infinite stream, and then limit it by the last y numbers, something like: ``` int x = MAGIC_NUMBER_X; int y = MAGIC_NUMBER_y; int sum = toList(FibonacciSupplier.infinite()) .stream() .skip(x) .limit(y) .mapToInt(i -> i) .sum(); ``` The code would not ever return a result, how should it be done?