在String源中,只有在方法public int hashCode()被调用至少一次时,才会设置哈希码值(private int hashCode)。这意味着一个不同的状态。但是hashCode是否会在以下示例中设置:
String s = "ABC"; ?
将
String s = "ABC";
s.hashCode();
帮助进行后续的比较表现?
答案 0 :(得分:12)
不可变意味着,从外部来看,不能改变对象的价值。
如果正在缓存hashCode
,则在第一次hashCode
调用后,对象的内部状态可能会有所不同。但是这个调用是只读的,你不能改变对象的外观世界的价值。
换句话说,它仍然是相同的字符串。
答案 1 :(得分:4)
技术上字符串已更改。第一次调用hashCode()
时会更改某些内部字段。
但是对于所有实际原因,字符串是不可变的。由于调用hashCode()
,哈希码的值不会改变,直到第一次调用时才会计算。对于字符串的任何使用者,字符串是不可变的。这才是最重要的。
答案 2 :(得分:3)
正如Robert Harvey和Greg所说,出于所有实际目的, String对象是不可变的(可能可以通过反射更改内容,但这是一个黑客攻击)。
在构建之后立即致电hashCode()
可能有助于理论上的表现。但是,出于所有实际目的,这是过早优化。
答案 3 :(得分:2)
但是hashCode会在以下示例中设置吗?
没有
[调用hashCode]会帮助进行后续的比较性能吗?
假设您的意思是后续拨打String.equals(Object)
,则答案为“否”。 equals
方法不使用String的hash
值,无论之前是否已计算过。
如果您指的是对String.hashCode()
的来电,答案是“可能不是”。至多你会得到一次性计算,以便尽早发生。 hashCode
方法仍然需要测试每次调用时hash
是否为零。
修改强>
我认为很明显,不同的JVM供应商以不同的方式实现String.equals。例如,@ Alex引用的IBM版本使用缓存的哈希码,但Sun的JDK 1.6中的版本不使用。
由此我们得出结论,任何为了“优化”String.hashCode()
而调用String.equals
的尝试都会产生依赖于JVM的结果。此外,对于@Alex正在使用的特定IBM JVM,看起来可能是有益的...前提是您已经为两个字符串完成了它。
但我仍然认为这是一个坏主意......除非你从分析中得到明确的证据String.equals()
是一个重要的瓶颈。
答案 4 :(得分:0)
没有。没有人打电话给它,所以没有打电话。
没有。怎样才能把一个方法称为额外的时间让事情变得更快?
答案 5 :(得分:-1)
这是实际的String.hashCode()实现:
public int hashCode() {
int h = hash; // hash is a field in String
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
所以: