简体   繁体   English

哈希映射条目冲突

[英]Hash Map entries collision

I am trying this code snippet 我正在尝试此代码段

Map headers=new HashMap();
headers.put("X-Capillary-Relay","abcd");
headers.put("Message-ID","abcd");

Now when I do a get for either of the keys its working fine. 现在,当我做一个get对任何按键的它的工作的罚款。 However I am seeing a strange phenomenon on the Eclipse debugger. 但是我在Eclipse调试器上看到了一个奇怪的现象。 When I debug and go inside the Variables and check inside the table entry at first I see this 当我调试并进入变量并首先检查table条目内部时,我看到了这一点

->table
--->[4]
------>key:X-Capillary-Relay
...........

However after debugging across the 2nd line I get 但是经过第二行调试后我得到了

->table
--->[4]
------>key:Message-ID
...........

Instead of creating a new entry it overwrites on the existing key. 它不会创建新条目,而是覆盖现有密钥。 For any other key this overwrite does not occur. 对于任何其他键,不会发生此覆盖。 The size of the map is shown 2. and the get works for both keys. 地图的大小显示为2.并且两个键的get适用。 So what is the reason behind this discrepancy in the eclipse debugger. 那么eclipse调试器中这种差异背后的原因是什么呢? Is it an eclipse problem? 这是日食问题吗? Or a hashing problem. 或者哈希问题。 The hashcode is different for the 2 keys. 对于2个键,哈希码是不同的。

The hashCode of the keys is not used as is. 键的hashCode不按原样使用。

It is applied two transformations (at least based on Java 6 code): 它应用了两个转换(至少基于Java 6代码):

static int hash(int h) {
    // This function ensures that hashCodes that differ only by
    // constant multiples at each bit position have a bounded
    // number of collisions (approximately 8 at default load factor).
    h ^= (h >>> 20) ^ (h >>> 12);
    return h ^ (h >>> 7) ^ (h >>> 4);
}

and

/**
 * Returns index for hash code h.
 */
static int indexFor(int h, int length) {
    return h & (length-1);
}

Since length is the initial capacity of the HashMap (16 by default), you get 4 for both keys : 由于length是HashMap的初始容量(默认为16),因此两个键都得到4:

System.out.println (hash("X-Capillary-Relay".hashCode ())&(16-1));
System.out.println (hash("Message-ID".hashCode ())&(16-1));

Therefore both entries are stored in a linked list in the same bucket of the map (index 4 of the table array, as you can see in the debugger). 因此,两个条目都存储在映射的同一个桶中的链表中( table数组的索引4 ,如调试器中所示)。 The fact that the debugger shows only one of them doesn't mean that the other was overwritten. 调试器只显示其中一个这一事实并不意味着另一个被覆盖。 It means that you see the key of the first Entry of the linked list, and each new Entry is added to the head of the list. 这意味着您可以看到链接列表的第一个条目的键,并且每个新条目都会添加到列表的开头。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM