To reuse a stream

Ricky Clarkson ricky.clarkson at gmail.com
Fri Feb 22 13:06:24 PST 2013


Thank you for the answer, a Supplier does indeed work for what I want.


On Fri, Feb 22, 2013 at 6:01 PM, Brian Goetz <brian.goetz at oracle.com> wrote:

> The fundamental question here is: whether a Stream is more like an
> Iterable, or an Iterator.  And it has been definitively answered -- the
> latter.
>
> 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 c.stream() on your
> collection.
>
> 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