2

one question

Map<Integer, Integer> map = new HashMap<>();
resMap.put(1, 1);
System.out.println(map.get(1L));
System.out.println(map.get(1));

You can see, what is the output of the above code? I will announce the answer later.

Source code analysis

The source code of the get method of HashMap is as follows (add your own notes):


public V get(Object key) {
    Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

/**
 * Implements Map.get and related methods.
 *
 * @param hash hash for key
 * @param key the key
 * @return the node, or null if none
 */
final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    // 如果map不为空
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        // 如果直接通过传进来的key找到了值,直接返回
        // 1)比较传进来key的hash值和在map中对应位置找到的结点的hash值是否一致
        // 2)比较传进来的key对象和在map中对应位置找到的结点的key对象(object)是否相等
        if (first.hash == hash && // always check first node
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        // 如果通过hash找到的结点的下一个节点不为空,说明是链表
        if ((e = first.next) != null) {
            // 如果是红黑树,直接红黑树查找
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            // 如果是普通链表,链表遍历查找
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    // 上述都不满足,返回null
    return null;
}

If the hash value corresponding to the passed key can match the node in the map (it can only be said that there is something in this position in the hash table (map)), the following two judgments are needed.

1) Compare the hash value of the key passed in and the hash value of the node found in the corresponding position in the map.

2) == Compare the key object passed in and the key object (object) of the node found at the corresponding position in the map for the same value ==

After reading the above source code analysis, we announced the answer:

null
1

The final difference is

(k = first.key) == key || (key != null && key.equals(k))

This code is equivalent to Objects.equals(key, k) .

The comparison here is that the key of the object stored in the map is named k, and the key passed to the map by the get

It is equivalent to comparing new Integer(1) and new Long(1L) . We know that they are two different objects, so the results are definitely not equal. So when the key is 1L, the result is null .

in conclusion

When the Map gets the value, the key type does not match, and the value cannot be obtained.


程序员伍六七
201 声望597 粉丝