首页 > 解决方案 > 为基于值的类预计算 hashCode?

问题描述

基于值的类具有它们的属性

是最终的和不可变的(尽管可能包含对可变对象的引用)。

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

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

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

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

标签: javahashcode

解决方案


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

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

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

所以缓存可能没有意义。可能是有道理的,String因为它在整个过程中如此普遍。可能值得头疼。


推荐阅读