HashMap中空键的哈希码

14

我刚刚在阅读有关 Java 中 HashMap 和 HashTable 类的区别。我发现它们之间的一个不同点是前者允许 null 键,而后者不允许。 就 HashMap 的工作原理而言,我知道它会在键上调用 hashcode 方法以查找要放置该键值对的桶。这里有我的问题: 如何计算 null 值的 hashcode 或者是否有默认值用于 null 键的 hashcode(如果有,请指定该值)?

6个回答

17

来自HashMap:

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

如果你再深入观察,就会发现 null 始终会进入 bin 0。


这是我从HashMap类代码中得到的,但是为了将该键值对放入bin 0中生成的哈希码是什么意思?0表示bin 0的哈希码值是多少。 - Prashant
这意味着null的哈希码为0,或者(理论上),任何满足num & (tableSize-1) == 0的数字。 - radai
你是想说对于空键来说,它的默认哈希值为0,并且会根据HashMap的实现将其放在第一个bin/桶中吗? - Prashant
jshell> Objects.hash(null). $11 ==> 0 - Sudip Bhandari

6

从HashMap的源代码中可以看出,如果键是null,它会被特殊处理。对于null,没有生成hashcode,但是它在内部数组中的索引0处唯一存储,并带有hash值0。同时需要注意的是,在字符串作为key的情况下,空字符串的hash值也是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;
}

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

0

它清楚地说明了当您使用已经存在于映射中的键进行put操作时会发生什么。key == null的特定情况行为相同:您不能为null键拥有两个不同的映射(就像您不能为任何其他键一样)。对于您问题的上下文来说,这不是一个特殊情况。


0

在内部,HashMap对键进行了空值检查。如果键为空,则返回0;否则返回键的哈希值。

而Hashtable没有任何空值检查,并直接调用键的hashcode方法。

这就是为什么Hashtable不接受空值的原因。


0
当地图中存在一个空值时,该值的键也是空的。在地图中不能有多个空键,只能有一个空键。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接