拆分器 getExactSizeIfKnown 与 estimateSize

spliterator getExactSizeIfKnown vs estimateSize

这是我在编写自定义 Spliterator 时想到的。我 知道 如果我知道大小,即使是近似值,我也应该覆盖 estimateSize。通常,我会这样做。但是还有 getExactSizeIfKnown,我知道它是默认实现:

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

现在,假设我正在研究 ArrayListSpliterator(我知道它已经存在,这不是重点)。我应该覆盖 getExactSizeIfKnownestimateSize 还是两者都覆盖?

在内部,我猜 getExactSizeIfKnown 实际上被调用了, 而不是 estimateSize - 因为第一个委托给第二个。考虑到理论上我正在研究 ArrayListSpliterator 不会 重写 getExactSizeIfKnown 实际上只是让我为一个额外的方法调用付费 - 绕行 getExactSizeIfKnown -> estimateSize?

“我应该覆盖 getExactSizeIfKnown 还是 estimateSize 或者两者都覆盖?”的答案也就是说,您必须按原样实施estimateSizeabstract。如果您看到原因,您可以另外覆盖 default 方法 getExactSizeIfKnown

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

没那么简单。为代码调用做好准备 getExactSizeIfKnown 因为它只有在精确并且没有检查特征的情况下才能使用该数字。但同时可以有其他代码调用 estimateSize,因为它 想要 估计,或者因为它将在另一个地方处理特征。一个人有一个 default 实现可以在特定条件下委托给另一个人,这一事实并没有说明调用者的任何事情。这些方法有不同的语义。

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?

可能 条件 比委托调用更有害,但如果您的特定 Spliterator 总是 returns 相同的特征,则 JVM 的优化器可能消除了与之相关的任何开销。因此,这是通常的权衡,在这里,与微小的开发工作相比,微小的潜在性能优势(提供仅返回已知数字的附加方法)。

如果大小的计算不是微不足道的,您无论如何都会以委托结束,因为您不希望重复重要的代码。而且,如果您的 class 的设计方式使得 SIZED 特性并不总是存在,那么无论如何您都将与 default 方法完全相同。