我只是想知道为什么在类的hashCode()方法中使用质数?例如,当使用Eclipse生成我的hashCode()方法时,总是使用素数31:
hashCode()
Eclipse
public int hashCode() { final int prime = 31; //... }
因为您想要乘以的数量以及要插入的存储桶的数量具有正交素数分解。
假设要插入8个桶。如果您要用来乘以的数字是8的倍数,则插入的存储桶将仅由最低有效项(一个根本没有相乘)确定。类似的条目将发生冲突。不适用于哈希函数。
31是一个足够大的素数,因此不可能被它整除(实际上,现代的Java HashMap实现将存储桶的数量保持为2的幂)。
选择质数以最好地在哈希存储桶之间分配数据。如果输入的分布是随机且均匀分布的,则哈希码/模的选择无关紧要。仅当输入具有特定模式时,它才有影响。
处理内存位置时通常是这种情况。例如,所有32位整数都对齐到可被4整除的地址。请查看下表,以直观了解使用质数模数与非质数模数的效果:
Input Modulo 8 Modulo 7 0 0 0 4 4 4 8 0 1 12 4 5 16 0 2 20 4 6 24 0 3 28 4 0
请注意,当使用质数模量与非质数模量时,分布几乎是完美的。
但是,尽管上面的示例在很大程度上是人为设计的,但总的原理是,当处理输入模式时,使用质数模将产生最佳分布。