【问题标题】:Hashcode for NULL key in HashMapHashMap 中 NULL 键的哈希码
【发布时间】:2013-06-20 12:44:49
【问题描述】:

我只是在阅读 Java 中 HashMap 和 HashTable 类之间的区别。在那里我发现了一个区别,前者允许空键,而后者不允许相同的权限。 就 HashMap 的工作而言,我知道,它在 key 上调用 hashcode 方法来查找要放置该键值对的存储桶。我的问题来了: 如何计算空值的哈希码或空键的哈希码是否有任何默认值(如果有,请指定值)?

【问题讨论】:

    标签: java collections hashmap


    【解决方案1】:

    来自 HashMap:

    public V put(K key, V value) {
       if (key == null)
          return putForNullKey(value);
       ...
    

    如果你进一步看,你会发现 null 总是进入 bin 0

    【讨论】:

    • 我从 HashMap 类代码中得到,但是为将该键值对放入 bin 0 中生成的哈希码是什么意思是 bin 0 的哈希码值是多少。
    • 这意味着 null 的哈希码是 0,或者(理论上)任何支持 num & (tableSize-1) == 0 的数字
    • 你是不是想说,对于null key,hashcode的默认值是0,按照HashMap的实现会使用第一个bin/bucket来放置。
    • jshell> Objects.hash(null)。 $11 ==> 0
    【解决方案2】:

    如果您阅读 HashMap 中static int hash(int h) 方法的描述,您会发现空键的索引为 0。

    【讨论】:

      【解决方案3】:

      当映射中存在空值时,该值的键也为空。地图中不能有很多空键。只有一个空键。

      【讨论】:

        【解决方案4】:

        从HashMap的源码来看,如果key为null则处理方式不同。没有为 null 生成哈希码,但它唯一地存储在内部数组的索引 0 处,哈希值为 0。另请注意,空字符串的哈希值也是 0(如果键是字符串),但它所在的索引存储在内部数组中,确保它们不会混淆。

         /**
         * Offloaded version of put for null keys
         */
        private V putForNullKey(V value) {
            for (Entry<K,V> e = table[0]; e != null; e = e.next) {
                if (e.key == null) {
                    V oldValue = e.value;
                    e.value = value;
                    e.recordAccess(this);
                    return oldValue;
                }
            }
            modCount++;
            addEntry(0, null, value, 0);
            return null;
        }
        

        【讨论】:

          【解决方案5】:

          它清楚地说明了当您使用地图中已经存在的键执行 put 时会发生什么。 key == null 的特定情况的行为方式相同:您不能对 null 键有两个不同的映射(就像您不能对任何其他键一样)。就您的问题而言,这不是特例。

          【讨论】:

            【解决方案6】:

            内部 Hashmap 对键有一个空检查。如果为 null 则返回 0 else 键的哈希值。

            因为 Hastable 没有任何 null 检查,它会直接调用 key 上的 hashcode 方法

            这就是 Hashtable 不接受 null 的原因。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-08-28
              • 2015-01-13
              • 1970-01-01
              • 2012-09-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-10
              相关资源
              最近更新 更多