为基于值的 类 预计算 hashCode?

Precompute hashCode for value-based classes?

基于值的 classes 具有 属性 他们

are final and immutable (though may contain references to mutable objects).

因此,如果您知道您的对象仅包含不可变实例,则可以预先计算该实例的 hashCode。这可以在使用 MapSet 操作时加快访问速度。

看看 InstanthashCode 的实现,这是一个基于值的 class,为什么开发人员决定反对这种模式?预先计算 hashCode 的性能损失是否会比在需要时一遍又一遍地计算更重要?

// copied from Instant#hashCode
@Override
public int hashCode() {
    return ((int) (seconds ^ (seconds >>> 32))) + 51 * nanos;
}

那么,在什么条件下预计算 hashCode 合理?

Instant 不缓存 hashcode 并没有直接的原因。但是我能想到的一些:

缓存hashcode是有代价的:声明的实例变量:

  • 它当然会占用每个对象更多的内存。重新计算哈希码可能没问题,而不是为每个实例对象分配额外的内存
  • 担心 serialization/deserialization,因为需要保留实例变量。增加序列化对象的大小
  • 内部实现在以后的版本中很难修改。尤其是因为过去的序列化对象。对于过去的版本对象,保持向后兼容性变得困难。额外维护。
  • hashcode 可能永远不会在 Instant 对象上调用。在这种情况下,我们浪费 CPU 来计算从未使用过的东西

所以缓存可能没有意义。可能对 String 有意义,因为它在整个过程中都很常用。可能值得头疼。