1.hashMap中的remove方法remove方法用来删除HashMap中指定key的映射关系,并返回删除的节点的value值,如果没有对应的key则返回null
方法中首先调用hash方法得到key的hash值,然后调用removeNode方法
2.HashMap中的removeNode方法removeNode方法首先查找HashMap中有没有指定的key值,然后根据找到的节点的类型进行删除
/**
* Implements Map.remove and related methods.
*
* @param hash hash for key
* @param key the key
* @param value the value to match if matchValue, else ignored
* @param matchValue if true only remove if value is equal
* @param movable if false do not move other nodes while removing
* @return the node, or null if none
*/
final Node<K,V> removeNode(int hash, Object key, Object value, boolean matchValue, boolean movable) {
Node<K,V>[] tab; Node<K,V> p; int n, index;
//table不为空,HashMap中存储有数据才继续执行
//根据传入key值的hash值和Node数组的长度-1进行与运算得到这个key对应的下标的元素p,p不为空则继续,否则说明没有存储这个key的映射关系
if ((tab = table) != null && (n = tab.length) > 0 && (p = tab[index = (n - 1) & hash]) != null) {
Node<K,V> node = null, e; K k; V v;
//如果Node数组的key值与传入的key相等,说明要删除的就是该元素,并赋值给node变量
if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
node = p;
//如果key对应的不是数组里面的元素并且该元素的next不为null,则继续查找
else if ((e = p.next) != null) {
//如果Node是TreeNode类型,说明该下标下的数据时红黑树的结构,调用红黑树的getTreeNode方法来查找节点并赋值给node
if (p instanceof TreeNode)
node = ((TreeNode<K,V>)p).getTreeNode(hash, key);
//如果不是红黑树结构,那就是链表的结构
else {
//遍历链表,根据key值查找对应的节点并赋值给node,如果找到则结束
//将该节点的前置节点赋值给p
do {
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) {
node = e;
break;
}
p = e;
} while ((e = e.next) != null);
}
}
//node不为null,说明HashMap中有该key对应的节点
//matchValue为false则直接进行删除动作,否则需要判断传入的value值与node的value值相同才删除,matchValue 默认为false
if (node != null && (!matchValue || (v = node.value) == value || (value != null && value.equals(v)))) {
//如果node是TreeNode类型,说明是红黑树,则调用红黑树的removeTreeNode方法进行删除
if (node instanceof TreeNode)
((TreeNode<K,V>)node).removeTreeNode(this, tab, movable);
//如果node==p,说明是删除Node数组中的元素,直接将node的下一个节点赋值到数组中即可
//如果只有一个元素,删除后则为null,如果是链表结构,就是删除链表的头部,数组中指向第二个节点即可
else if (node == p)
tab[index] = node.next;
//如果是链表结构且不是头部,则直接删除链表中的节点
//p为要删除的节点的前置节点,node为要删除的节点,直接删除即可
else
p.next = node.next;
//HashMap修改次数自增,size自减
modCount;
--size;
afterNodeRemoval(node);
return node;
}
}
return null;
}
|