我正在通过Java为hashtable实现put方法,并且遇到了这个问题:
// Makes sure the key is not already in the hashtable.
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
V old = e.value;
e.value = value;
return old;
}
}
虽然我知道需要密钥来检查冲突,但为什么Java存储密钥的哈希值并检查它?
答案 0 :(得分:8)
因为同一个桶(tab
)可以保存由于% tab.length
操作而具有不同哈希值的项目。首先检查哈希值可能是一些性能优化,以避免在哈希值不同时调用equals()
。
举一个例子:假设你有两个复杂的对象,使用昂贵的equals()
方法。一个对象具有等于1的散列,而另一个对象具有32的散列。如果将两个对象放在具有31个桶的散列表中,它们将最终位于同一个桶中(tab
)。添加第二个(不同的对象)时,必须确保它还没有在表中。您可以立即使用equals()
,但这可能会更慢。相反,您首先要比较哈希值,如果没有必要,请避免使用昂贵的equals()
。在此示例中,哈希值不同(尽管存在于同一个存储桶中),因此不需要equals()
。
答案 1 :(得分:1)
它使访问速度更快,因为不需要为每次访问重新计算哈希值。这不仅对于显式搜索(在执行equals
之前检查哈希)而且对于重新哈希也很重要。