14

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

4

6 回答 6

16

来自 HashMap:

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

如果你看得更远,你会发现 null 总是进入 bin 0

于 2013-06-24T04:56:17.270 回答
6

从 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;
}
于 2013-06-24T04:59:15.533 回答
3

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

于 2013-06-24T04:58:10.037 回答
0

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

于 2013-06-24T04:58:31.943 回答
0

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

于 2015-03-26T13:23:25.727 回答
0

内部 Hashmap 对键有一个空检查。如果它为空,那么它将返回 0 否则键的哈希值。

其中 Hastable 没有任何空值检查,它将直接调用键上的 hashcode 方法

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

于 2020-10-07T13:46:01.733 回答