有人可以解释这些常数的意义,为什么选择它们?
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-se6库
解决方法
了解什么使一个好的散列函数是棘手的,因为实际上有很多不同的功能使用和略有不同的目的.
Java的哈希表工作如下:
他们要求关键对象生成其哈希码. hashCode()方法的实现可能具有明显变化的质量(在最坏的情况下返回一个常量值!),并且绝对不会适用于您正在使用的特定哈希表.
>然后,他们使用上述功能将比特混合在一起,使得高位中存在的信息也被移到低位.这很重要,因为下一个…
>他们使用散列码的mod(w.r.t.哈希表数组条目的数目)来获取哈希表链数组中的索引.哈希表数组的大小相当于2的幂,所以在步骤2中比特的混合很重要,以确保它们不会被丢弃.
>然后他们遍历链,直到他们使用相等的键(根据equals()方法)到达条目.
要完成图片,散列表数组中的条目数是非常数;如果链条太长,那么数组将被一个新的更大的数组所替代,并且所有的数据都被重新排列.这相对较快,对正常使用模式具有良好的性能影响(例如,大量的put()跟随很多get()s).
所使用的实际常数是相当任意的(并且可能通过实验使用一些简单的语料库来选择,包括诸如大量的整数和String值的事情),但是它们的目的不是:将整个值中的信息扩展到大部分低位该值确保使用hashCode()的输出中存在的信息以及可能.
(你不会使用完美的散列或加密散列来做到这一点;尽管类似的名称,它们具有非常不同的实现策略,前者需要知道关键空间,以避免/减少冲突,后者需要移动信息在各个方向,不仅仅是低位.)