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
?
The answer to “Should I override
getExactSizeIfKnown
orestimateSize
or may be even both?” is, you must implementestimateSize
as it isabstract
. You may additionally override thedefault
methodgetExactSizeIfKnown
if you see a reason.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 callingestimateSize
, either because it wants an estimate or because it will processes the characteristics at another place. The fact that one has adefault
implementation that may delegate to the other under a certain condition doesn’t say anything about the caller. These methods have different semantics.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 thedefault
method anyway.