为了扩展David Richerby的答案,术语“ 哈希函数 ”有点重载。通常,当我们谈论哈希函数时,我们会想到MD5,SHA-1或类似Java的.hashCode()
方法,它们会将一些输入转换为一个数字。但是,此数字的域(即最大值)不太可能与您要存储数据的哈希表的大小相同。(MD5是16个字节,SHA-1是20个字节,并且.hashCode()
是int
-4个字节)。
因此,您的问题是有关下一步的问题-一旦我们有了一个可以将任意输入映射到数字的哈希函数,如何将它们放入特定大小的数据结构中?具有另一个功能,也称为“哈希函数”!
这种函数的一个简单例子是模 ; 您可以轻松地将多个任意大小映射到模中数组中的特定索引。这在CLRS中被称为“除法”:
ķ米ķ米
h (k )= k米
...
米米m = 2ph (k )pķ
〜算法简介,第11.3.1节-CLRS
米
Java HashMap
使用除法的修改版本,该方法执行预处理步骤以解决较弱的.hashCode()
实现,因此它可以使用二乘幂数组。您可以确切地看到该.getEntry()
方法中发生了什么(评论是我的):
// hash() transforms key.hashCode() to protect against bad hash functions
int hash = (key == null) ? 0 : hash(key.hashCode());
// indexOf() converts the resulting hash to a value between 0 and table.length-1
for (Entry<K,V> e = table[indexFor(hash, table.length)];
...
Java 8带来了HashMap
更快的重写速度,但更难读取。但是,它使用相同的一般原则进行索引查找。