Intermediate stream operations not evaluated on count

The count() terminal operation, in my version of the JDK, ends up executing the following code:

if (StreamOpFlag.SIZED.isKnown(helper.getStreamAndOpFlags()))
    return spliterator.getExactSizeIfKnown();
return super.evaluateSequential(helper, spliterator);

If there is a filter() operation in the pipeline of operations, the size of the stream, which is known initially, can’t be known anymore (since filter could reject some elements of the stream). So the if block is not executed, the intermediate operations are executed and the StringBuilder is thus modified.

On the other hand, If you only have map()in the pipeline, the number of elements in the stream is guaranteed to be the same as the initial number of elements. So the if block is executed, and the size is returned directly without evaluating the intermediate operations.

Note that the lambda passed to map() violates the contract defined in the documentation: it’s supposed to be a non-interfering, stateless operation, but it is not stateless. So having a different result in both cases can’t be considered as a bug.

Leave a Comment