Expected behavior of a Streams.cycled() instance - found issues and questions
Brian Goetz
brian.goetz at oracle.com
Tue Oct 23 10:11:35 PDT 2012
Thanks for the questions. Bear in mind that most of the methods in
Streams are experimental.
> In the current API there is a utility class java.util.streams.Streams
> which contains besides others method cycled().
>
> There are few problems and questions regarding how a properly cycled
> stream should behave
> in terms of conforming to the standard contract of the Stream interface.
>
> Some of the questions apply to any infinite stream.
>
> 0) (Sorry if this has been discussed already) - is there any legal way
> to get flags of a random Stream instance?
Currently, there is not. However, we might consider adding a
getStreamFlags() method on BaseStream.
> 1) Should it be allowed (as it is now) to concat to the end of an
> infinite (cycled for example) stream?
It doesn't seem so useful, but also such attempts to protect the user
from themselves are also often counterproductive, especially if "known
infinite" really means "probably infinite." For example, what about:
infiniteStream.filter(t -> false)
So the answer is "maybe, but maybe not."
> 2) Getting next element of a flatMap of a cycled stream leads to hanging:
> Streams.cycle(Arrays.asList(1, 2, 3)).flatMap((Block<Object> sink,
> Integer element) -> {}).iterator().next();
That seems like a bug...
> 3) cycledStream.noneMatch((obj) -> false)) leads to hanging as well
> though it probably should not.
>
> 4) Getting iterator for a sorted cycled stream leads to
> java.lang.OutOfMemoryError: Java heap space
> Streams.cycle(Arrays.asList(1, 2,
> 3)).sorted(Comparators.<Integer>reverseOrder()).iterator();
Yes, this is expected -- sorting an infinite stream takes infinite time
and space. Its a fair question as to how far we should go to protect
the user from this. Users can create infinite loops now; we trust them
to know whether they terminate.
> 5) cycledStream.uniqueElements() leads to IllegalStateException though
> it should not according to common sense.
Well, I'm not sure I agree with the notion of common sense here; I think
its a bit much to ask the runtime to do this kind of analysis. But this
is a fine example of the sort of trouble we get in when we do try and
protect the user from themselves; this ISE is exactly what you're asking
for in (1), and we should probably remove it.
> 6) This will lead to hanging:
> Streams.cycle(Arrays.asList(1, 2, 3)).filter((obj) ->
> false).iterator().hasNext();
>
> 7) This will lead to hanging as well:
> Streams.cycle(Arrays.asList(1, 2, 3)).allMatch((obj) -> true);
>
> 8) And this hangs up also:
> Streams.cycle(Arrays.asList(1, 2, 3)).anyMatch((obj) -> false);
Yes. I think these are reasonable.
More information about the lambda-dev
mailing list