未从put()插入HashMap内的值

时间:2018-02-12 08:19:16

标签: java hashmap

请考虑以下代码段:

public class MainClass {

public static void main(String[] arg)       {
    Map<String, Object> map = new HashMap<>();

    map.put("ONE", new BigInteger("1"));
    map.put("TWO", new BigInteger("2"));
    map.put("THREE", new BigInteger("3"));
    map.put("FOUR", new BigInteger("4"));
    map.put("FIVE", new BigInteger("5"));
    map.put("SIX", new BigInteger("6"));

    System.out.println("Hello !");
}

结果是:

  • 地图的size为6。
  • 地图的table包含以下内容:

    [FIVE=5,
     SIX=6,
     ONE=1,
     TWO=2,
     THREE=3]
    

FOUR消失了。正如之前所述的评论,计算我的条目的hashCode是明智的,以模块的大小为模。它给出了以下结果:

ONE : 0
TWO : 0
THREE : 1
FOUR : 2
FIVE : 3
SIX : 4

正如我们所看到的,hashCode并未表明考虑FOUR与任何值的冲突。这也适用于ConcurrentHashMapLinkedHashMap,因此我认为这是一个HashMap问题。

有人可以向我解释实际发生了什么吗?我很遗憾这个。

我正在使用:

  • Eclipse Neon
  • JDK 8

2 个答案:

答案 0 :(得分:4)

&#34; FOUR&#34;并没有消失。您亲眼看到地图的大小为6,如果您打印地图,则会看到所有6个条目。

如果你在调试器中仔细观察,你会看到那些键&#34; ONE&#34;和&#34;四&#34;映射到同一个桶(索引7)。即使他们没有相同的哈希码,也会发生这种情况(因为HashMap会对密钥的hashCode()执行一些额外的计算,然后对结果执行% table.length获取桶的索引。)

enter image description here

在您的示例中,为&#34; ONE&#34;计算的哈希值是&#34;四&#34;是78407由于默认的初始桶数为16,因此桶的计算方式为78407%16 == 2163975%16 == 7,因此两个密钥都存储在同一个桶中。

答案 1 :(得分:4)

HashMap的内部表(实际上是一个简单的数组)不存储值,而是存储类似结构的结构,其元素现在存储多个值。

哈希映射计算放入其中的键的哈希值。具有相同哈希码的不同键进入同一列表(在表数组中编入索引)。

查看HashMap.Node的源代码:

static class Node<K,V> implements Map.Entry<K,V> {
    final int hash;
    final K key;
    V value;
    Node<K,V> next;
    ...
}

该列表中的每个节点都存储密钥,值,哈希码以及指向该列表下一个节点的指针。

您的示例代码构建了下表:

 [2] FIVE = 5    =>   null
 [3] SIX = 6     =>   null
 [7] ONE = 1     =>   FOUR = 4   =>   null
[13] TWO = 2     =>   null
[15] THREE = 3   =>   null

顺便说一下......打印整个地图会产生以下结果:

{FIVE=5, SIX=6, ONE=1, FOUR=4, TWO=2, THREE=3}