【发布时间】:2020-08-03 20:00:33
【问题描述】:
我的问题很简单。
什么时候计算字符串的哈希码?
- 创建字符串时,还会计算哈希码,并且在构造完成后总是在 O(1) 内准备就绪
- 仅在第一次调用
hashCode方法时计算哈希码,并在 O(1) 时间内为所有后续调用做好准备 - 每次调用
hashCode方法时都会计算哈希码
选项 1 似乎是合理的,因为字符串是不可变的。给定字符串的哈希码永远不会改变。但是,这会减慢字符串的创建速度,因此使用选项 2 似乎也是合理的。选项 3 看起来很傻而且浪费时间,但是因为没有存储哈希码,所以可以节省空间。选项 3 是我没有考虑过的最佳方法可能还有一些合乎逻辑的原因。
提前非常感谢
【问题讨论】:
-
@khelwood 真的吗?调用 hashCode 后,String 对象的哈希码以某种方式被缓存?缓存在哪里?在对象?我认为是选项 3
-
您可以查看
String的源代码,看看它是在第一次调用时计算和缓存的。 *如何*这与不变性一起工作是另一回事,最好留给专家。简短的回答是它有点不像。如果两个线程及时调用hashCode(),则很有可能两者最终都会分别计算哈希码的值。这是可行的,因为字符串字符永远不会改变,因此将始终计算相同的哈希码。 -
请注意,Java
Strings 的哈希码不会在任何这些点计算;他们只是发生。 OpenJDK 使用 (2) 的事实是一个实现细节。 -
@chrylis-cautiouslyoptimistic- 我不确定你的意思。如果你的意思是“hashCode 的缓存行为不是外部指定的”,是的,这是公平的。如果需要,它当前的实现可能会改变。但是,在 Java 25 年多的历史中,
hashCode一直是这样计算的。