HashMap源码分析3:移除
本文源码基于JDK1.8.0_45。
1 final Node<K,V> removeNode(int hash, Object key, Object value, 2 boolean matchValue, boolean movable) { 3 Node<K,V>[] tab; Node<K,V> p; int n, index; 4 //如果HashMap未初始化或哈希值对应下标无节点,不需要执行移除操作 5 if ((tab = table) != null && (n = tab.length) > 0 && 6 (p = tab[index = (n - 1) & hash]) != null) { 7 Node<K,V> node = null, e; K k; V v; 8 //头节点等于目标元素 9 if (p.hash == hash && 10 ((k = p.key) == key || (key != null && key.equals(k)))) 11 node = p; 12 else if ((e = p.next) != null) { 13 //如果是树结构,调用红黑树的接口获取目标节点 14 if (p instanceof TreeNode) 15 node = ((TreeNode<K,V>)p).getTreeNode(hash, key); 16 else { 17 //链表结构,遍历整个链表 18 do { 19 if (e.hash == hash && 20 ((k = e.key) == key || 21 (key != null && key.equals(k)))) { 22 node = e; 23 break; 24 } 25 p = e; 26 } while ((e = e.next) != null); 27 } 28 } 29 //如果移除前需要判断节点的值,则目标值与原值相等才能移除 30 if (node != null && (!matchValue || (v = node.value) == value || 31 (value != null && value.equals(v)))) { 32 //调用红黑树的接口移除树节点 33 if (node instanceof TreeNode) 34 ((TreeNode<K,V>)node).removeTreeNode(this, tab, movable); 35 //如果目标元素等于头节点的值,移除对头节点的引用,指向下一个节点 36 else if (node == p) 37 tab[index] = node.next; 38 //如果是链表结构,则前序节点的next指向要移除节点的下一个节点 39 else 40 p.next = node.next; 41 ++modCount; 42 --size; 43 afterNodeRemoval(node); 44 return node; 45 } 46 } 47 return null; 48 }