Java 简单散列函数技术

Java 简单散列函数技术,java,hashtable,Java,Hashtable,我对Java中的散列非常陌生,我一直被一些部分卡住了。我有一个400个项目的列表(存储在1.5x=600的列表中),项目id的范围为1-10k。我一直在研究一些散列函数,最初我复制了数据包中的示例,它只是使用了折叠。我注意到我得到了大约50-60%的空节点,这显然太多了。我还注意到,只需将id修改600就可以将其减少到50%的空值 我当前的散列函数看起来有点像,尽管它很难看,但它的空值仅比简单的修改减少了1%,平均列表长度为1.32 public int getHash( int id )

我对Java中的散列非常陌生,我一直被一些部分卡住了。我有一个400个项目的列表(存储在1.5x=600的列表中),项目id的范围为1-10k。我一直在研究一些散列函数,最初我复制了数据包中的示例,它只是使用了折叠。我注意到我得到了大约50-60%的空节点,这显然太多了。我还注意到,只需将id修改600就可以将其减少到50%的空值

我当前的散列函数看起来有点像,尽管它很难看,但它的空值仅比简单的修改减少了1%,平均列表长度为1.32

   public int getHash( int id )
   {
      int hash = id;

      hash <<= id % 3;
      hash += id << hash % 5;

      /* let's go digit by digit! */          
      int digit;
      for( digit = id % 10;
           id != 0;
           digit = id % 10, id /= 10 )
      {
         if ( digit == 0 ) /* prevent division by zero */
            continue;
         hash += digit * 2;
      }

      hash >>= 5;
      return (hash % 600);
   }
public int-getHash(int-id)
{
int hash=id;

hash有一篇很好的评论文章。另外,是一篇很好的概述。它建议使用卡方检验来评估hash函数的质量。

我会保持它的简单性。返回元素的
id
作为hashcode,如果需要,让hashtable担心对它进行重新灰化。你的目标应该是创建对象特有的哈希代码

Java HashMap使用以下重新灰化方法:

/**
 * Applies a supplemental hash function to a given hashCode, which
 * defends against poor quality hash functions.  This is critical
 * because HashMap uses power-of-two length hash tables, that
 * otherwise encounter collisions for hashCodes that do not differ
 * in lower bits. Note: Null keys always map to hash 0, thus index 0.
 */
static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}