java - 为基于值的类预计算 hashCode?
问题描述
基于值的类具有它们的属性
是最终的和不可变的(尽管可能包含对可变对象的引用)。
因此,如果您知道您的对象仅包含不可变实例,则可以预先计算hashCode
实例的。Map
这可以在使用或Set
操作时加快访问速度。
查看hashCode
from的实现Instant
,这是一个基于值的类,为什么开发人员决定反对这种模式?预计算的性能损失会hashCode
比需要时一遍又一遍地计算更重要吗?
// copied from Instant#hashCode
@Override
public int hashCode() {
return ((int) (seconds ^ (seconds >>> 32))) + 51 * nanos;
}
那么,在什么条件下预计算是合理的hashCode
呢?
解决方案
Instant
为什么不缓存没有直接的原因hashcode
。但我能想到的一些:
缓存hashcode
是有代价的:声明的实例变量:
- 它当然会占用每个对象更多的内存。重新计算哈希码可能会更好,而不是为每个实例对象分配额外的内存
- 担心序列化/反序列化,因为需要保留实例变量。增加序列化对象的大小
- 在未来的版本中,内部实现变得难以修改。由于过去的序列化对象,尤其如此。对于过去的版本对象,保持向后兼容性变得困难。额外的维护。
hashcode
可能永远不会在 Instant 对象上调用。在这种情况下,我们将 CPU 浪费在计算从未使用过的东西上
所以缓存可能没有意义。可能是有道理的,String
因为它在整个过程中如此普遍。可能值得头疼。
推荐阅读
- angular - Angular Monorepo:如何解决两个耦合模块的循环依赖关系(httpservice 记录发送的内容/使用 httpservice 发送的所有日志)
- reactjs - 添加产品成功后如何清除ReactJs中的表单输入
- javascript - 在三元运算符内进行类型检查后,打字稿没有推断出正确的类型
- android - 带有 su -c 的 adb shell 命令给出权限被拒绝(手机已植根)
- python - Loop (while True:) 直接将第一个输入作为 else 语句,但在后续尝试中工作正常
- javascript - HTML:如何在输入中输入自动滚动?(添加的最后一件事必须始终可见)
- javascript - 如何将滚动条添加到反应组件?
- database - 将 ms access 2013 数据库与 vb.net 应用程序连接时出错
- django - testdriven.io django 在尝试访问 postgres 时在 heroku 上提高了 500
- javascript - 持久数据、纯函数和 RAM