HashMap中的空键和空值

3

HashMap 允许一个 null 键和多个 null 值。

我想知道 HashMap 如何处理 null 键/值?我的意思是它在内部是如何处理的?


3
JDK附带源代码,请阅读。 - JB Nizet
6
一切都有源代码,这并不意味着在stackoverflow上寻求捷径是个坏主意。如果您不能在这里提出这样的问题,我不明白stackoverflow的目的是什么。 Null显然没有哈希映射依赖的 .hashcode() 方法。所以,这是一个完美的问题。我不明白为什么明显很糟糕的问题,比如http://stackoverflow.com/questions/18310177,没有被投反对票,但是正常的问题仍然得到了大量的反对票。我们的道德观念颠倒了,想把stackoverflow变成管道。 - Val
这是一个有效的问题,如果没有负面评价,本应该得到适当的回答。 - sakura
3个回答

3
HashMap定义了两个私有方法来处理null键:
  • 如果键为null,则从get(K key)方法调用getForNullKey()方法
  • 如果键为null,则从put(K key,V value)方法调用putForNullKey(V value)方法。
你可以在源代码中找到它们。
并且处理null值没有太多需要担心的地方。它们被视为普通值。

2

如果您查看源代码,它维护了不同的方法来处理null值。

 Offloaded version of put for null keys
408 
409     private V More ...putForNullKey(V value) {
410         for (Entry<K,V> e = table[0]; e != null; e = e.next) {
411             if (e.key == null) {
412                 V oldValue = e.value;
413                 e.value = value;
414                 e.recordAccess(this);
415                 return oldValue;
416             }
417         }
418         modCount++;
419         addEntry(0, null, value, 0);
420         return null;
421     }



Offloaded version of get() to look up null keys. Null keys map to index 0. This null case is split out into separate methods for the sake of performance in the two most commonly used operations (get and put), but incorporated with conditionals in others.
334 
335     private V More ...getForNullKey() {
336         for (Entry<K,V> e = table[0]; e != null; e = e.next) {
337             if (e.key == null)
338                 return e.value;
339         }
340         return null;
341     }

0

处理HashMap中的Null键和值

http://javaexplorer03.blogspot.in/2015/11/how-null-key-is-handled-in-hashmap.html

由于equals()和hashCode()用于存储和检索值,那么在空键的情况下它是如何工作的呢?

HashMap中特别处理了空键,有两个单独的方法putForNullKey(V value)和getForNullKey()。后者是get()的卸载版本,用于查找空键。空键始终映射到索引0。

为了性能考虑,这种空键情况被拆分成了两个最常用操作(get和put)的单独方法,并与其他条件合并。

简而言之,在HashMap中,当涉及到空键时,equals()和hashcode()方法不会被使用,以下是从HashMap中检索空值的方法。

private V getForNullKey() {
    for (Entry<K,V> e = table[0]; e != null; e = e.next) {
        if (e.key == null)
            return e.value;
    }
    return null;
}

/**
 * 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;
}

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