这个hashCode有意义吗?

Does this hashCode make sense?

我遇到了一些执行以下操作的哈希码函数:

class MyClass{
   private String string;
   //..other data members and methods...
   public int hashCode()
   { 
        int result = 17;
        if(string != null)
        {
           result = result*31 + string.hashCode;
        }
        return result;
   }
};

我不完全相信用于计算 hashCode 的方法,我知道使用质数通常会产生更好的分布。但是在这个实现中,我并不真的相信是这样。

例如,假设一个标准的哈希实现,我会错过 0 到 17*31 之间的所有桶。

是否有一些我没有看到的微妙之处?

您遗漏了溢出情况,这在 hashCode 实现中很可能发生。

特别是,string.hashCode可以是负数。

如问题 Is the hashCode function generated by Eclipse any good? (originally duped against this answer, reopened by request), this hashCode function matches implementations built into Java and recommended by Java co-author Joshua Bloch in Effective Java Item 9. This is similar to the Annotation docs, which prescribe a hash function that is the sum of (member value hash code) xor (127 * member name hash code) for all members. By picking prime numbers to start out with--here, 17 and 31--the hash factors would be necessarily coprime.

Objects.hashCode 文档中所述,重要的是 hashCode 在运行之间保持一致,与 equals 一致,并且如果可行则不同。

散列码设计的一个主要因素是散列码会环绕。如 the OpenJDK8 code for HashMap:

Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
    (first = tab[(n - 1) & hash]) != null) {

table 长度,必须是 2 的幂,成为 hashCode 的掩码:对于大小为 64 的散列 table,散列的位掩码为 63,0b00111111.给定质数“哈希涂抹”,这些低位将是 well-distributed,不多于或少于 17 和 31 因子存在于 single-field 哈希函数中,但如果存在则特别有利两个、三个或五十个字段都被组合到一个散列函数中。返回的 hashCode 的绝对大小无关紧要,只要哈希码的适当低位是 well-distributed.