javajava-8java-streamspliterator

spliterator getExactSizeIfKnown vs estimateSize


This came up as I was writing a custom Spliterator. I know I should override estimateSize if I know the size, even an approximative one. And usually, I do. But then there is getExactSizeIfKnown and I understand it's default implementation:

default long getExactSizeIfKnown() {
    return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
}

Now, suppose I am working on an ArrayListSpliterator (I understand it already exists, that is not the point). Should I override getExactSizeIfKnown or estimateSize or may be even both?

Internally, I guess getExactSizeIfKnown is actually called, not estimateSize - since the first one delegates to the second. Taking into consideration that theoretically I am working on a ArrayListSpliterator, will not overriding getExactSizeIfKnown actually just make me pay for one extra method call - the detour getExactSizeIfKnown -> estimateSize?


Solution

  • The answer to “Should I override getExactSizeIfKnown or estimateSize or may be even both?” is, you must implement estimateSize as it is abstract. You may additionally override the default method getExactSizeIfKnown if you see a reason.

    Internally, I guess getExactSizeIfKnown is actually called, not estimateSize - since the first one delegates to the second.

    It’s not that simple. Be prepared for code calling getExactSizeIfKnown because it may utilize that number only if being exact and hasn’t checked the characteristics. But at the same time there can be other code calling estimateSize, either because it wants an estimate or because it will processes the characteristics at another place. The fact that one has a default implementation that may delegate to the other under a certain condition doesn’t say anything about the caller. These methods have different semantics.

    Taking into consideration that theoretically I am working on a ArrayListSpliterator, will not overriding getExactSizeIfKnown actually just make me pay for one extra method call - the detour getExactSizeIfKnown -> estimateSize?

    It’s likely that the conditional hurts more than a delegation call, but if your specific Spliterator invariably returns the same characteristics, the JVM’s optimizer likely eliminates any overhead connected with that. So it’s the usual trade-off, here, a tiny potential performance benefit over a tiny development effort (for providing an additional method just returning a known number).

    If the calculation of the size is not trivial you would end up at delegation anyway, as you don’t want duplication of nontrivial code. And if your class is designed in a way that the SIZED characteristic is not always present, you would do exactly the same as the default method anyway.