根據源碼可知,HashMap的get方法流程不是特別複雜,其中真正執行取值的邏輯是在getNode()方法中,不多說直接上源碼。
這裏再囉嗦一句:其中入參hash是調用了存值時的hash()方法,就是根據將key進行hash得到hash值,然後將hash值與Key進行異或操作(可以理解爲加密),再進行無符號右移16位得到的。
/**
* 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) {
//tab爲hashmap中存放鏈表的數組,first是鏈表表頭
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
//判斷鏈表數組是否爲空,即當前hashmap是否爲空,並且根據Key計算出數組下標,進而獲取目標所在鏈表(或紅黑樹)的頭結點
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
//判斷鏈表頭結點的值是否是所要獲取的目標值,如果不是則不進入if
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
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);
}
}
return null;
}