hash算法的应用场景
Java中的Map实际是一个“散列表”的数据结构,散列表是逻辑上由一系列可存放词条(或其引用)的单元组成,故这些单元也称作桶(bucket) —— 一般都使用线性表来实现。
一组词条在散列表内部的具体分布,取决于所谓的散列(hashing)方案:事先在词条与桶地址之间约定的某种映射关系,可描述为从关键码空间到桶数组地址空间的函数: hash() 。
这里的hash()称作散列函数(hash function)。反过来,hash(key)也称作key的散列地
址(hashing address),亦即与关键码key相对应的桶在散列表中的位置。
所有散列函数都有如下一个基本特性:根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。但是,根据同一散列函数计算出的散列值如果相同,输入值不一定相同。对于java而言即如果 hashcode方法返回相同,equals方法不一样返回相同。但equals方法返回相同,则hashcode必须相同。
最佳的情况是充分利用有限的散列表空间,即散列函数最好是满射(定义域R与散列表的单元一一对应)。
当然,因定义域规模R远远大于散列表空间规模,散列函数不可能是单射。这就意味着,关键码不同的词条被映射到同一散列地址的情况称作散列冲突(collision)。
主流的hash算法有如下:
除余法:
将散列表长度M取作为素数(只有为素数才能让其分布更加均匀http://zhao