我对使用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);
   }


创建简单的哈希函数有哪些好的技术?

最佳答案

我会保持简单。将元素的id返回为您的哈希码,让哈希表担心是否需要重新哈希。您的目标应该是使哈希码对您的对象唯一。

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);
}

关于java - 简单的哈希函数技术,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5642881/

10-16 12:37