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 }

 

posted @ 2019-03-21 21:55  lwpimis  阅读(120)  评论(0编辑  收藏  举报