remove(Object key)功能:删除指定的key对应的元素。
/*
* 删除节点
* Object key:需要删除的key
* */
public V remove(Object key) {
HashMap.Node<K,V> e; //定义Node类型的节点e
/*
* 调用removeNode(hash(key), key, null, false, true),把执行结果赋值给e,如果e为空,则返回null,否则返回要删除的key对应的value
* */
return (e = removeNode(hash(key), key, null, false, true)) == null ?
null : e.value;
}
remove方法中直接调用了removeNode(hash(key), key, null, false, true),所以本文重点注释了removeNode方法。
final HashMap.Node<K,V> removeNode(int hash, Object key, Object value,
boolean matchValue, boolean movable) {
/*
* 定义Node类型的数组tab,node类型的节点p,定义tab的长度n,tab下标index
* */
HashMap.Node<K,V>[] tab; HashMap.Node<K,V> p; int n, index;
if ((tab = table) != null && (n = tab.length) > 0 && //把hashMap成员变量table赋值给tab,且tab不为空,长度大于0
(p = tab[index = (n - 1) & hash]) != null) { //通过给定的hash值计算key在数组tab中的位置index,如果tab[index]不为空,如果这个位置已经有元素存储了,p:存放当前节点
HashMap.Node<K,V> node = null, e; K k; V v; //定义Node节点node,用户存放将要删除的节点,e:用于存放链表上的节点,定义中间变量k,v
if (p.hash == hash && //如果当前节点的hash值等于给定的hash,且当前节点的ke等于给定的key
((k = p.key) == key || (key != null && key.equals(k))))
node = p; //把当节点p赋值给node;
else if ((e = p.next) != null) { //如果p的下一个节点不为空,说明该位置有链表或红黑树,把p志向的下一个节点赋值给e
if (p instanceof HashMap.TreeNode) //如果当前节点是红黑树
node = ((HashMap.TreeNode<K,V>)p).getTreeNode(hash, key); //走红黑树的删除节点的分支
else { //如果当前节点是链表,通过while循环找到链表中和给定的hash和key一样的节点(待删除节点),赋值给node
do {
if (e.hash == hash &&
((k = e.key) == key ||
(key != null && key.equals(k)))) { //如果链表上的节点e的hash等于给定的hash,e的key等于给定的key,代表找到了要删除的节点e,赋值给node
node = e;
break; //退出while
}
p = e; //如果e的hash、key不等于给定的hash,key,链表往下循环
} while ((e = e.next) != null);//退出循环条件,为啥是e = e.next?
}
}
if (node != null && (!matchValue || (v = node.value) == value ||
(value != null && value.equals(v)))) { //如果node不为空,不需要匹配value,node的value和给定的value相同
if (node instanceof HashMap.TreeNode) //node是红黑树
((HashMap.TreeNode<K,V>)node).removeTreeNode(this, tab, movable); //走红黑树分支删除node
else if (node == p) //node是数组
tab[index] = node.next; //删除node
else
p.next = node.next; //node在链表上,删除链表上的node
++modCount; //记录hashMap被修改的次数
--size;//hashMap长度减一
afterNodeRemoval(node);//回掉函数
return node; //返回被删除的节点
}
}
return null;//返回
}
|