Java 仓位指数计算中循环的消除
这是一个例子 它提供以下代码来获取bin的索引: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(散列
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的构造函数。;)