hashmap里面两个最重要的方法就是get
和put
一、put(Object key)
方法的实现
public V put(K key, V value){
//调用putval
return putval(hash(key), key, value, false, true);
}
putval()
的基本思路:
1.要是table
为空,则创建新的table
2.要是table[(length-1)&hash(key)]
为空,则创建新节点,否则(即原来有节点):
(1)如果key的hash值和这个节点的hash值相同,且key相同,则把这个节点的value改为新的值,key不变;
(2)如果该链为树,调用putTreeVal()
,基本思想也应该是遍历,遇到相同的就改变value, 要是没相同key的节点就在树后加新节点
(3)其他情况,也就是链为单链,然后table上的那个节点key不一样,就遍历单链,遇到相同的就改变value,没有遇到就在链尾加新节点
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {
Node<K, V>[] tab; Node<K, V> p;
int n; //长度
int i; //索引
if((tab = table) == null || (n == tab.length) == 0)
n = (tab = resize()).length;
if((p = tab[i = (n-1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else{
Node<K, V> e; //指向要改变的节点
K k; //被放入元素的key值
if(hash == p.hash && ((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if(p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else{
for(int binCount = 0; ;++binCount){ //遍历
if((e = p.next) == null){
p.next = newNode(hash, key, value, null);
if(binCount >= TREEIFY_THRESHOLD - 1)
treeifyBin(tab, hash);
break;
}
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
if (e != null) {
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
二、get(Object key)和containsKey(Object key)的实现
public V get(Object key){
Node<K, V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
public boolean containsKey(Object key){
return getNode(hash(key), key) != null;
}
getNode()
的基本思路:
(1)首先要保证table不为空,长度不为0并且table[(n-1)&hash]
不为空,否则返回null
(2)首先检查第一个节点即table
上的节点,如果hash值和key值都相等,就返回这个节点的value
(3)如果首节点不是要找的点,就往后遍历直到找到hash值和key值都和要找的点相同的节点,如果后面是树,则调用找查树的方法。
final Node<K, V> getNode(int hash, Object key){
Node<K, V>[] tab; Node<K, V> first, e; int n; K k;
if((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n-1) & hash]) != null){
if(first.hash == hash && ((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;
}