最近面试遇到面试官有提到哈希算法,可能比较重要,于是找资料学习整理了一下。
现实中有个应用场景:比如快递站有1000个快递,但只有10个货架,每个货架有5层,要将这1000个快递放入这50层内。
平均下来,每一层放入20个快递,但由于快递尺寸大小,每层可能放入的数量可能不一样。
取快递就直接说取件号,比如第3个快递柜的第2层可以是:0302;第13个快递柜的第4层可以是:1304。
于是,存在以下4个现象:
两个相同货物,一定存放在同一个货架的同一层;
两个不同货物,不一定存放在同一个货架的同一层;
同一个货架的同一层,可能有两个不同货物;
不在同一个货架的同一层,肯定不是同一个货物。
哈希(hash),就是把任意输入,散列为固定长度的输出,这个输出就是哈希值(散列值)。
类似于快递站存放货物,不可能存在足够多的格子分配给每个货物。现实中,不可能将每个键值都对应一个哈希值 ,可能多个键值都对应一个哈希值。
哈希算法 |
---|
两个对象相等,hashCode一定相等 |
两个对象不等,hashCode不一定相等 |
hashCode相等,两个对象不一定相等 |
hashCode不等,两个对象一定不相等 |
有几种常见的哈希算法
- 除法哈希
hash(key) = key mod M
M一般为素数
- 乘法哈希
hash(key) = floor( M/W * ( a * key mod W) )
注意:
通常设置 M 为 2 的幂次方。
W 为计算机字长大小(也为2的幂次方)。
a 为一个非常接近于W的数。
Java就用乘数为31的乘法哈希来求hashCode