To reuse a stream

Brian Goetz brian.goetz at
Fri Feb 22 13:01:22 PST 2013

The fundamental question here is: whether a Stream is more like an 
Iterable, or an Iterator.  And it has been definitively answered -- the 

We flirted with a design that put Stream methods on Iterable, and it had 
all sorts of problems, many of which come down to: a Stream has no clue 
what its source is or whether it is repeatable -- and shouldn't.  (Note 
that the specification for iterator() in Iterable isn't even clear on 
this either.)

The word "stream" indicates a flow; the values flow by, and once a value 
has gone by, its gone.

If your source is repeatable (say, an immutable collection), then you 
don't need a new abstraction -- just keep calling on your 

More generally, you can always use Supplier to add the level of 
indirection you seek:

   Supplier<IntStream> streamMaker
       = () -> Streams.intRange(2, MAX_VALUE);

And then you can call streamMaker.get() as many times as you like. 
There's no need for a StreamMaker / StreamSource / Streamable abstraction.

On 2/22/2013 3:23 PM, Ricky Clarkson wrote:
> Hi,
> If I run the following:
> IntStream numbers = Streams.intRange(2, Integer.MAX_VALUE);
> IntStream primes = numbers.filter(x -> x < 3 ||
> numbers.limit(x).noneMatch(y -> x % y == 0));
> primes.limit(100).forEach(System.out::println);
> I get an IllegalStateException at the forEach call: Stream is already
> linked to a child stream, which was a surprise.  I guessed that the problem
> is that I'm using the same stream twice recursively.  The following works
> fine:
> IntStream numbers = Streams.intRange(2, Integer.MAX_VALUE);
> IntStream primes = numbers.filter(x -> x < 3 || Streams.intRange(2, x -
> 1).noneMatch(y -> x % y == 0));
> primes.limit(100).forEach(System.out::println);
> This seems an odd design, I wouldn't naturally expect such a Stream to have
> a problem with concurrent/recursive use.  It means that a Stream is an
> object I need to protect/manage the ownership of, like an Iterator, and not
> so much like an Iterable, even if the underlying data source is immutable.
>   Is this deliberate?  If so will there be another abstraction that can be
> used and shared more freely?
> Ricky.

More information about the lambda-dev mailing list