Java 中 String hashCode() 的旧实现中跳过字符背后的想法是什么
What is the idea behind skipping chars in the old impl of String hashCode() in Java
在旧版本的 Java 的 String hashCode() 实现中跳过 String 中的某些字符的想法是什么:
public int hashCode() {
int hash = 0;
int skip = Math.max(1, length()/8);
for (int i = 0; i < length(); i += skip)
hash = (hash * 37) + charAt(i);
return hash;
}
当前版本没有跳过,素数是31而不是37
可能是为了加快 hashCode()
计算速度,但结果它有更多潜在的冲突。
新版本有利于减少碰撞但需要更多计算。
但事实上,String
s 是不可变的,因此在 hashCode()
的较新版本中,计算一次:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
hash = h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
}
return h;
}
所以在某种程度上支持这种方式是有意义的,因为它减少了冲突次数并且不跳过 hashCode()
计算中的某些字符并不像缓存结果那样昂贵。
在旧版本的 Java 的 String hashCode() 实现中跳过 String 中的某些字符的想法是什么:
public int hashCode() {
int hash = 0;
int skip = Math.max(1, length()/8);
for (int i = 0; i < length(); i += skip)
hash = (hash * 37) + charAt(i);
return hash;
}
当前版本没有跳过,素数是31而不是37
可能是为了加快 hashCode()
计算速度,但结果它有更多潜在的冲突。
新版本有利于减少碰撞但需要更多计算。
但事实上,String
s 是不可变的,因此在 hashCode()
的较新版本中,计算一次:
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
hash = h = isLatin1() ? StringLatin1.hashCode(value)
: StringUTF16.hashCode(value);
}
return h;
}
所以在某种程度上支持这种方式是有意义的,因为它减少了冲突次数并且不跳过 hashCode()
计算中的某些字符并不像缓存结果那样昂贵。