peek().iterator().hasNext() pre-consumes elements?
georgiy.rakov at oracle.com
Wed Feb 20 07:02:35 PST 2013
it has just come into my mind that it could be quite more major issue
than I wrote in my previous letter.
So the case a bit rewritten:
Stream s1 = Arrays.asList(1, 2, 3).stream();
Stream s2 = s1.peek(System.err::println);
The spec says:
Produce a Stream containing the elements of this stream, and also
provide elements to the specified Consumer as elements are *passed
So the core question is what does "passed through" mean?From the first
glance I would say it means *consuming elements from **stream returned
****by peek()* (not from stream which peek() is applied to). If this
interpretation is right then I could suppose it's a bug because the
element from s2 has not been consumed yet (next() is not called just
hasNext() has been called).
Could you please confirm if such reasoning is right and it's really a bug.
On 12.02.2013 23:01, Remi Forax wrote:
> On 02/12/2013 07:16 PM, Brian Goetz wrote:
>> The answer here is complicated, but in general, calling hasNext may well
>> require consuming an element -- there's often no way to know whether a
>> source would produce an element without asking it to do so. So it is a
>> common practice in implementing iterators to do this (one of many
>> reasons why we did not build Streams on Iterator.)
>> Because the elements are coming from an array, it might be possible to
>> know simply based on how many elements have gone by that the stream is
>> not yet exhausted. But in the general case (such as when the stream
>> source is an IO channel), it is not possible to know without actually
>> consuming and buffering some input. So I would put this in the category
>> of "acceptable" behavior. We might someday do some work to take
>> advantage of the fact that the source has the SIZED characteristic and
>> the pipeline stages are size-preserving to make this case behave
>> "better", but that would be an implementation quality issue, not a spec
>> issue. The behavior you observe is allowable by the spec.
> while I a stream may have to do some buffering, peek should always be
> transparent and an iterator on an array doesn't need any buffering but I
> agree that this is an implementation issue.
>> On 2/12/2013 12:53 PM, Dmitry Bessonov wrote:
>>> The following line prints out the first element, "1"
>>> Arrays.asList(1, 2,
>>> Is it really an expected behavior?
More information about the lambda-dev