哈希方法

问题描述:

可能重复:
Explanation of HashMap#hash(int) method哈希方法

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

谁能解释详细此方法,谢谢。

+2

来源评论相当详细。你想了解什么?目的?位移逻辑?别的东西? – Fredrik

+0

@Foredoomed我可以说这只是一堆XOR环和位移位,但其背后的逻辑可能更为复杂。 – Eugene

+2

我认为这是这个问题的重复

设计一个通用散列码的问题之一是,你将所有这些努力都放在确保位的良好传播上,然后有人出现并以这种方式使用它来完全撤销那。

我们来看一个带有X和Y(两个整数)的坐标类的经典示例。

这是一个典型的例子,因为人们会用它来证明X^Y不是一个好的散列码,因为通常有几个对象,其中X == Y(全部散列为0)或者其X和Y是另一个的Y和X(将散列相同)和其他情况下,我们最终使用相同的散列码。

归结为这样一个事实,即整数有一个可能的范围,覆盖了四十亿个值,在99%的使用中,它们往往最多少于几百或几万。我们永远无法摆脱试图在四十亿个可能的结果中传播18quadrillion可能的价值,但我们可以努力使那些我们可能真正看到的,不太可能发生冲突。

现在,(X << 16 | X >> 16)^Y在这种情况下做得更好,将X中的位扩展得更多。

不幸的是,如果使用该散列的是做% someBinaryRoundNumer索引到一个表(或甚至% someOtherNumber,到稍微较小的程度上),那么对下面someBinaryRoundNumber X的值 - 其中我们可以期望是最常见的 - 这个散列有效地变为return Y

我们所有的辛苦工作都浪费了!

重复使用的是用这样的逻辑做一个散列,稍微好一点。

值得注意的是,对(X << 16 | X >> 16)^Y方法太过挑剔是不公平的,因为散列的另一种用法可能具有优于给定备选方案的形式。

那么不进入到精细的细节,但:

  • 由于hascode()和equals()的合同,一个执行不力的哈希码功能可能会导致具有相同的哈希码不同实例。这意味着你可能有一个类用一个糟糕的hashcode()方法实现,这样类的equals()方法将为A和B实例返回false(这意味着它们与业务逻辑的角度不同)但hashcode()方法为实例A和B返回相同的值。同样,根据hashcode()和equals()合约,这在技术上是有效的,但不是很合适的

  • in a Htabletable-like structure如HashMap)“桶”用于根据其哈希码将映射放置在映射内部。如果两个实例具有相同的哈希码()(但根据equas()方法不同),它们将被放置在同一个存储桶中。从性能角度来看,这是不好的,因为当你有很多这样的情况时,你会失去一些类似Hashtable结构固有的检索速度。被称为碰撞。发生什么事情是,如果稍后有人使用“搜索”实例从hashmap中检索某些内容,并且相应的哈希桶具有多个占有者,则必须使用equals()方法检查该存储桶中的每个元素,以找出哪个是需要检索的那个。在极端情况下,HashMap可以像这样转换成链表。

  • hash(int n)方法为现有的hashcode()值添加了一些额外的东西,以便防御这种情况。