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

Georgiy Rakov georgiy.rakov at
Wed Feb 20 06:02:27 PST 2013

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.
> Rémi
I agree with Rémi that stream could do some buffering.

But regarding if it's an implementation issue or not I see it as follows.
This issue doesn't affect the *main purpose* of peek() that is to 
produce the same stream while iterating through its elements. But such 
behavior could be quite frustrating for experienced user because 
intuitively there is a way could be seen for implementation to avoid 
consuming the element (buffering). Such way doesn't always exist by the 
way, for instance for the following case: 
stream().filter(p).iterator().hasNext() - what is quite obvious for 
experienced user. So from the point of view that this issue doesn't 
affect the *main purpose* of peek() it could be seen as an 
implementation issue. But from the other hand it could be seen as /minor 
/(_not implementation_) issue because its result is visible through 
public API and this result could be quite frustrating.


>> 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