Java 仓位指数计算中循环的消除

Java 仓位指数计算中循环的消除,java,algorithm,Java,Algorithm,这是一个例子 它提供以下代码来获取bin的索引: private int getIndex(K key) { int hash = key.hashCode() % nodes.length; if (hash < 0) hash += nodes.length; return hash; } private int getIndex(K键) { int hash=key.hashCode()%nodes.length; if(散列

这是一个例子

它提供以下代码来获取bin的索引:

private int getIndex(K key)
{
    int hash = key.hashCode() % nodes.length;
    if (hash < 0)
        hash += nodes.length;
    return hash;
}
private int getIndex(K键)
{
int hash=key.hashCode()%nodes.length;
if(散列<0)
hash+=nodes.length;
返回散列;
}
要确保哈希值不大于表的大小, 用户提供的哈希函数的结果用于对 桌子的长度。我们需要指数非负,但是 如果左操作数 (散列值)为负数,因此我们必须对其进行测试并使其为负数 非负的

如果
hash
结果是非常大的负值,则循环中添加的
hash+=nodes.length
可能需要大量处理

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


如果是这样的话,如何实现呢?

这不可能是一个很大的负数。

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

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

它不可能是一个很大的负数。

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

if (hash < 0) /* `if', not `while' */
    hash += nodes.length;
if(hash<0)/*'if',而不是'while'*/
hash+=nodes.length;
这不是实际使用的方法

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

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

此时的哈希值必须介于
-length+1
length-1
之间,因此它不能是非常大的负值,如果它是负值,代码将无法工作。无论如何,不管价值有多大,成本总是一样的。

这不是实际使用的方法

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

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


此时的哈希值必须介于
-length+1
length-1
之间,因此它不能是非常大的负值,如果它是负值,代码将无法工作。无论如何,不管价值有多大,成本都是一样的。

噢。你是对的。我错过了
if
,总是看到
而不是
。在
if
的情况下,它已经是
O(1)
。你是对的。我错过了
if
,总是看到
而不是
。在
if
的情况下,它已经是
O(1)
。按位AND的好技巧。但只有当
长度
是2的幂时,它才会起作用。为什么这个条件成立?当
length
是2的幂时,比这小一个是像000…000111…111这样的数字,也就是说,一个0的块和一个1的块,这意味着丢弃顶端的位,其作用与
%
相同,只是它是无符号的,因为顶端的位被丢弃,速度更快,因为它很简单。顺便说一句,一段相关的代码是用来测试一个数字是二的幂
n!= 0&&(n&(n-1))==0我从你的回答中得到了窍门。但是我不明白为什么
长度
是2的幂。现在我明白了,如果我们需要测试n是2的幂,它并不总是成立的。所以,我想,为了使这个算法有效,我们应该确保长度始终是2的幂。@ovgolovin Its始终是2的幂,因为代码确保它是。请参阅HashMap的构造函数。;)伟大的技巧与按位和。但只有当
长度
是2的幂时,它才会起作用。为什么这个条件成立?当
length
是2的幂时,比这小一个是像000…000111…111这样的数字,也就是说,一个0的块和一个1的块,这意味着丢弃顶端的位,其作用与
%
相同,只是它是无符号的,因为顶端的位被丢弃,速度更快,因为它很简单。顺便说一句,一段相关的代码是用来测试一个数字是二的幂
n!= 0&&(n&(n-1))==0我从你的回答中得到了窍门。但是我不明白为什么
长度
是2的幂。现在我明白了,如果我们需要测试n是2的幂,它并不总是成立的。所以,我想,为了使这个算法有效,我们应该确保长度始终是2的幂。@ovgolovin Its始终是2的幂,因为代码确保它是。请参阅HashMap的构造函数。;)