[英]Why the calculation of hash in HashMap(JDK1.8) don't need to consider the negative hashCode as ConcurrentHashMap does?
In HashMap
: (h = key.hashCode()) ^ (h >>> 16);
在
HashMap
: (h = key.hashCode()) ^ (h >>> 16);
In ConcurrentHashMap
: (h ^ (h >>> 16)) & HASH_BITS;
在
ConcurrentHashMap
: (h ^ (h >>> 16)) & HASH_BITS;
where HASH_BITS
is 0x7fffffff
, by & HASH_BITS
it can always be a positive number.其中
HASH_BITS
是0x7fffffff
,通过& HASH_BITS
它总是可以是正数。
Why the calculation of hash in HashMap(JDK1.8) don't need to consider the negative hashCode as ConcurrentHashMap does?
为什么HashMap(JDK1.8)中的hash计算不需要像ConcurrentHashMap那样考虑负hashCode?
Ultimately, the case where the hash is negative (after spreading) does need to be considered in the HashMap
case as well.最终,在
HashMap
情况下也需要考虑散列为负(传播后)的情况。 It is just that this happens later in the code.只是这发生在代码的后面。
For example, in getNode
(Java 8) you find this:例如,在
getNode
(Java 8) 中,您会发现:
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
Since tab.length
is a power of 2, tab.length - 1
is a suitable bitmask for reducing hash
to a subscript for the array.由于
tab.length
是 2 的幂,因此tab.length - 1
是一个合适的位掩码,用于将hash
减少到数组的下标。
You can rest assured that in every implementation of HashMap
or ConcurrentHashMap
there is some code that reduces the hash code to a number that is suitable for use as a subscript.您可以放心,在
HashMap
或ConcurrentHashMap
每个实现中,都有一些代码可以将哈希码简化为适合用作下标的数字。 It will be there ... somewhere.它会在那里……某个地方。
But also ... don't expect the code of these classes to be easy to read.但也...不要指望这些类的代码很容易阅读。 All of the collection classes have been reworked / tuned multiple times get the best possible (average) performance over a wide range of test cases.
所有集合类都经过多次重新设计/调整,在各种测试用例中获得最佳(平均)性能。
Actually it handles negative index calculations.实际上它处理负指数计算。 It's not evident at first looking but there are calculations in some places while accessing the elements(key or value).
乍一看并不明显,但在访问元素(键或值)时在某些地方进行了计算。
int index =
(n - 1) & hash
, in which n
is length of the table int index =
(n - 1) & hash
,其中n
是表的长度
It simply handles negative indexing.它只是处理负索引。
AFAIK, HashMap
always uses arrays sized to a power of 2 (eg 16
, 32
, 64
, etc.). AFAIK,
HashMap
总是使用大小为 2 的幂的数组(例如16
、 32
、 64
等)。
Let's assume we have capacity of 256
( 0x100
) which is 2^8
.假设我们的容量为
256
( 0x100
),即2^8
。 After subtraction 1, we get 256 - 1 = 255
which is 0x100 - 0x1 = 0xFF
The subtraction gives rise to get the proper bucket index between 0
to length-1
with exact bit mask needed to bitwise-and with the hash.减 1 后,我们得到
256 - 1 = 255
,即0x100 - 0x1 = 0xFF
减法产生了在0
到length-1
之间获得正确的桶索引,以及按位和散列所需的精确位掩码。
256 - 1 = 255
0x100 - 0x1 = 0xFF
A hash of 260
( 0x104
) gets bitwise-anded with 0xFF
to yield a bucket number of 4
. 260
( 0x104
) 的散列与0xFF
进行按位与运算以产生桶号4
。
A hash of 257
( 0x101
) gets bitwise-anded with 0xFF
to yield a bucket number of 1
. 257
( 0x101
) 的散列与0xFF
进行按位与运算以产生桶号1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.