peek().iterator().hasNext() pre-consumes elements?

Remi Forax forax at
Tue Feb 12 11:01:01 PST 2013

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:
>> Hello,
>> The following line prints out the first element, "1"
>>      Arrays.asList(1, 2,
>> 3).stream().peek(System.err::println).iterator().hasNext()
>> Is it really an expected behavior?
>> -Dmitry

More information about the lambda-dev mailing list