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() 计算速度,但结果它有更多潜在的冲突。
新版本有利于减少碰撞但需要更多计算。

但事实上,Strings 是不可变的,因此在 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() 计算中的某些字符并不像缓存结果那样昂贵。