提问者:小点点

这个hashCode有意义吗?


我遇到了一些哈希代码函数,它具有以下功能:

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之间的所有桶。

是不是有些微妙的地方我没看出来?


共2个答案

匿名用户

正如在Eclipse生成的hashCode函数有什么好处吗?这个hashCode函数匹配Java中内置的实现,并由Java合著者Joshua Bloch在《有效Java第9项》中推荐。这类似于注释文档,它为所有成员规定了一个哈希函数,即(成员值哈希码)xor(127*成员名称哈希码)的总和。通过选择素数开始——这里是17和31——哈希因子必然是相互关联的。

与Objects.hashCode文档中一样,重要的是hashCode在运行之间是一致的,与< code>equals一致,并且如果可行的话是不同的。

关于哈希代码设计的一个主要因素是哈希代码将环绕。如在哈希图的开放JDK8代码中:

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) {

表长度(必然是 2 的幂)成为 hashCode 的掩码:对于大小为 64 的哈希表,哈希得到的位掩码为 63, 0b00111111。给定素数“哈希涂抹”,这些低位将分布良好,不比单字段哈希函数中存在17和31个因子更多或更少,但如果将两个,三个或五十个字段全部组合成一个哈希函数,则特别具有优势。返回的哈希码的绝对大小无关紧要,只要哈希码的适当低位分布良好即可。

匿名用户

您缺少溢出情况,这在hashCode实现中很可能发生。

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