哈希表哈希避免负哈希码

Posted

技术标签:

【中文标题】哈希表哈希避免负哈希码【英文标题】:Hashtable hashing avoid negative hashcode 【发布时间】:2012-09-16 00:00:55 【问题描述】:

我想知道为什么Hashtable 避免使用负哈希码?

int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;

(hash & 0x7FFFFFFF) 使有符号位从 0 变为正数,但为什么我们不能将有符号的 32 位整数视为无符号?甚至使用模块化技巧使其变得积极。例如,

public static long int_mod(int hashcode, int tab_length)
     return (hashcode % tab_length + tab_length) % tab_length;  
 

【问题讨论】:

我认为这种方法简单有效。可能这就是它被使用的原因。 (hash & 0x7FFFFFFF) 缩小到正,% tab.length 缩小到标签大小。简单干净容易。 你指的是哪种方法?最初的实现? 是的。已经实现了。 整数除法和取模是迄今为止最慢的操作(在当代 Intel/AMD CPU 上可能是 40 个周期),而 & 属于最便宜的操作集(1 个周期,可以并行执行) .因此,您的解决方案将花费大约两倍于原始解决方案的时间。 【参考方案1】:

该值必须介于0tab.length - 1 之间,因为它用作存储值(和溢出元素)的内部数组(在本例中为tab)的索引。因此,它不能为负数。

我假设 (hash & 0x7FFFFFFF) % tab.length 优先于 (hashcode % tab.length + tab.length) % tab.length 使用,因为它更快,不会过度增加冲突的机会,但您必须找到设计文档或与原始开发人员交谈才能确定。

【讨论】:

【参考方案2】:

...但是为什么我们不能...

您在问为什么选择特定的实现。没有人能告诉你这一点,除非是代码的原始作者,如果他或她记得的话。

总是有多种方法可以在代码中实现一个想法。编写代码的人必须选择其中之一。事后问为什么没有选择另一个特定的实现是没有多大意义的。

【讨论】:

我没有检查过,但我猜是这样。为什么您对它的实现方式不满意? @Jesper:恕我直言,这确实很有意义,所以我们可以从这个决定中学习。当然,很多时候没有人可以肯定地说,但是可以找到并评估论点。这使问题成为一种讨论,在 SO 上不受欢迎,但它非常有用。【参考方案3】:

如果你的容量是 2 的幂,

private static final int CAPACITY = 64;
private static final int HASH_MASK = CAPACITY - 1;

final int index = obj.hashCode() & HASH_MASK;

基本上,屏蔽掉除您感兴趣的低位之外的所有位。假设低 N 位的分布与整个哈希码一样均匀。

【讨论】:

【参考方案4】:

Java 没有原生的无符号类型。如果hashCode 有负值,那么我们将不得不在使用hashCode 作为数组索引的任何地方应用这种屏蔽技巧。

【讨论】:

【参考方案5】:

我们不能将有符号的 int 视为无符号的表面上是有一个很好的理由:最初的 Java 开发人员认为无符号支持是不必要的复杂化,因为无符号算术可以是 confusing。从那以后,这对 Java 来说并不是一个足够大的问题来解决。

作为verdesmerald mentioned,由于没有明确的记录说明为什么选择(hash & 0x7FFFFFFF) % tab.length而不是出于您巧妙修改的效果,尽管我们可以找到该决定的理由,但最终我们只能推测为什么会这样做.

语义的最后一点,这可能并不那么重要:Hashtable 没有使用负哈希码,而是哈希码被“转换”为索引的非负形式。

【讨论】:

【参考方案6】:

没有人能告诉你为什么原作者选择了那个实现,除了他自己(也许还有他的同事)。无论如何这并不重要,因为它工作正常。

关于您提议的实现:它可能没有按照您认为应该做的那样做。您应该刷新 java 中 % 运算符的实际作用:For example here。将整数溢出添加到混合中,您建议的表达式可能会导致负值...

【讨论】:

以上是关于哈希表哈希避免负哈希码的主要内容,如果未能解决你的问题,请参考以下文章

哈希码冲突解法示意图

深度分析及实现哈希表

mysql-哈希索引

数据结构 | java中 哈希表及其冲突解决

哈希表、哈希算法、一致性哈希表

哈希索引