Yes, there is a way to do this, but with some limitations.
Stream<Integer> infiniteStream = Stream.iterate( 0, x -> new Integer(x + 1) );
Iterator<Integer> iter = infiniteStream.iterator();
Integer zero = iter.next();
Integer one = iter.next();
Alternatively,
Stream<Integer> infiniteStream = Stream.iterate( 0, x -> new Integer(x + 1) );
Spliterator<Integer> spliterator = infiniteStream.spliterator();
spliterator.tryAdvance(i -> System.out.println(i)); // zero
spliterator.tryAdvance(i -> System.out.println(i)); // one
Given a Stream
, it's possible to get an Iterator
or Spliterator
from it, or to query whether it's a parallel stream, etc. These are defined on the BaseStream
interface, a superinterface of Stream
, which makes them a bit easy to miss.
In this case we know the stream is infinite, so there is no need to call the Iterator's hasNext()
method or to check the return value of the Spliterator's tryAdvance()
The limitation is that both the iterator()
and spliterator()
methods of Stream
are terminal operations which means that after they're called, the returned Iterator or Spliterator has exclusive access to the values represented by the Stream. Further operations on the stream (such as filter
or map
and so forth) are not permitted and will be met with IllegalStateException
.
If you wanted to peel off the first couple elements and then resume stream processing, you could turn a spliterator back into a stream like so:
Stream<Integer> stream2 = StreamSupport.stream(spliterator, false);
This will probably work fine for some things, but I'm not sure I'd recommend this technique in general. I think it adds a few extra objects and thus extra method calls in the path of producing the next element.
Editorial comments (not related to your question):
- Don't use
new Integer(val)
. Instead use Integer.valueOf(val)
which will reuse the boxed integer if it's available, which is generally true for values in the range -128 to 127.
- You can use
IntStream
instead of Stream<Integer>
which avoids boxing overhead entirely. It doesn't have the full complement of stream operations, but it does have iterate()
which takes a function that operates on primitive int
values.