摆脱bin索引计算中的循环

时间:2012-11-28 09:31:22

标签: java algorithm

这是implementation of HashMap

它提供了获取bin的索引的代码:

private int getIndex(K key)
{
    int hash = key.hashCode() % nodes.length;
    if (hash < 0)
        hash += nodes.length;
    return hash;
}
  

要确保哈希值不大于表的大小,   用户提供的散列函数的结果以模数形式使用   桌子的长度。我们需要索引是非负的,但是   如果左操作数,模数运算符(%)将返回负数   (哈希值)是负数,所以我们必须测试并制作它   非负

如果hash的值为非常大的负值,则周期中的hash += nodes.length加法可能需要大量处理。

我认为它应该有O(1)算法(独立于hash值)。

如果是这样,怎么能实现呢?

2 个答案:

答案 0 :(得分:3)

这不是一个非常大的负数。

anything % nodes.length的结果总是小于nodes.length的绝对值,因此您需要一个if,而不是一个循环。这正是代码所做的:

if (hash < 0) /* `if', not `while' */
    hash += nodes.length;

答案 1 :(得分:1)

这不是HashMap在现实中使用的方法。

272       /**
273        * Returns index for hash code h.
274        */
275       static int indexFor(int h, int length) {
276           return h & (length-1);
277       }

这是有效的,因为length始终是2的幂,这与无符号 % length

相同
  

如果散列是非常大的负值,则循环中的加法散列+ = nodes.length可能需要大量处理。

此时的哈希值必须介于-length+1length-1之间,因此它不能是一个非常大的负值,如果确实如此,代码将不起作用。无论如何,价值有多大并不重要,成本总是相同的。