在查看openjdk-1.6 的 java.lang.String 的源代码时,我看到 String.hashCode() 使用 31 作为素数并计算
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
现在我看这个的原因是我想到的问题是比较 String.equals 中的 hashCodes 是否会使 String.equals 显着更快。但是现在看hashCode,我想到了以下问题:
- 更大的素数是否有助于更好地避免冲突,至少对于短字符串来说,例如“BC”与“Ab”具有相同的哈希值(因为 ascii 字母位于 65-122 区域,所以不会是素数比那个工作更好)?
- 使用 31 作为素数是有意识的决定,还是只是因为它很常见而随机使用?
- 给定固定字符串长度,哈希冲突的可能性有多大?这个问题的标题是原始问题,比较 hashCodes 和字符串长度有多好已经可以辨别字符串,以避免比较实际内容。
- 有点离题,也许:String.equals 没有将 hashCodes 比较为额外的快捷方式有充分的理由吗?
- 离题一点:假设我们有两个内容相同但实例不同的字符串:有没有办法在不实际比较内容的情况下断言相等?我猜不会,因为以某种方式进入字符串长度,空间会爆炸成大小,我们将不可避免地发生冲突,但是一些限制呢 - 只有某个字符集,最大字符串长度......以及我们需要限制多少字符串空间能有这样的散列函数吗?