Search code examples
javajava-8java-streamspliterator

Why does Spliterator's getExactSizeIfKnown() NOT call hasCharacteristics()


In the source (JDK 1.8.0_40) of the Spliterator class, the default implementation of getExactSizeIfKnown() checks to see if the instance being operated upon has the SIZED characteristic directly by calling the abstract characteristics() method and checking if it contains SIZED, rather than calling just calling the hasCharacteristics(SIZED) method, which has a default implementation which does pretty much the same thing.

Is there any reason why getExactSizeIfKnown() is not implemented as:

return !hasCharacteristics(SIZED) ? -1L : estimateSize();

which reads clearer to me and seems to handle overriding the default behaviour better (currently, if hasCharacteristics(int) is overriden to something bizzare, there is no indication that getExactSizeIfKnown() should probably also be overriden)?

Is there something I'm missing here? Why duplicate the check between methods like this?


Solution

  • This question apparently came up during the design of the Spliterator class. Quoting Paul Sandoz in this discussion on the OpenJDK mailing list:

    Post by Mike Duigou
    - getExactSizeIfKnown() - use hasCharacteristics?

    We could, it is marginally more efficient not to.

    So it seems there was no strong reason, only a minor performance consideration.

    On another note, I don't think your argument about overriding hasCharacteristics(int) to "something bizarre" really holds. If you were to override hasCharacteristics(int), the implementation of characteristics() would also need to be consistent with that "bizarre" behaviour, else you would be breaking the contract of the Spliterator. Note that the implementation specification (which describes required behaviour of conforming implementations) of getExactSizeIfKnown() says:

    The default implementation returns the result of estimateSize() if the Spliterator reports a characteristic of SIZED, and -1 otherwise.

    Based on that, if you override the behaviour of the Spliterator characteristics, you have been warned that getExactSizeIfKnown() will be, by default, impacted.