高效的hashCode()实现

Ada*_*ski 13 java algorithm hashmap hashcode data-structures

我经常hashCode()使用IntelliJ IDEA 自动生成类的方法,通常该方法采用以下形式:

result = 31 * result + ...
Run Code Online (Sandbox Code Playgroud)

我的问题是乘以31的目的是什么?我知道这是一个素数,但为什么选择31?此外,如果hashCode()为特别小/大的数据集实现a ,人们会以不同的方式处理这个问题吗?

Jon*_*eet 21

乘以31是快速的,因为JIT可以将其转换为左移5位和减法:

x * 31 == (x << 5) - x
Run Code Online (Sandbox Code Playgroud)

没有任何特别的额外信息,我会坚持这种方法.它的速度相当快,并且可能最终得到分布均匀的哈希码,并且它也很容易正确:)

数据集的大小并不重要,但如果你有关于你将使用的值的特定额外信息(例如"它总是偶数"),那么你可以设计一个更好的哈希函数.我会等到第一个真正的问题但是:)

  • 7允许仅在两个相邻字符中不同的字符串通常以相同的哈希码结束.实际上,过去十年或二十年代的任何处理器都应该能够在一个周期内管理乘以8位数(只要它在寄存器中). (6认同)
  • 那为什么不7?这是3和减法的转变.这是一个素数 (2认同)
  • 上次我检查31也是素数. (2认同)