JDK1.8中HashMap的源码分析( 三 )

[] newTab = (Node[])new Node[newCap];//赋予当前的tabletable = newTab;//此处自然是把old中的元素 , 遍历到new中if (oldTab != null) {for (int j = 0; j < oldCap; ++j) {//临时变量Node e;//当前哈希桶的位置值不为null , 也就是数组下标处有值 , 因为有值表示可能会发生冲突if ((e = oldTab[j]) != null) {//把已经赋值之后的变量置位null , 当然是为了好回收 , 释放内存oldTab[j] = null;//如果下标处的节点没有下一个元素if (e.next == null)//把该变量的值存入newCap中 , e.hash//该节点为红黑树结构 , 也就是存在哈希冲突 , 该哈希桶中有多个元素else if (e instanceof TreeNode)//把此树进行转移到newCap中((TreeNode)e).split(this, newTab, j, oldCap);else { /**此处表示为链表结构 , 同样把链表转移到newCap中 , 就是把链表遍历后 , 把值转过去 , 在置位null**/Node loHead = null, loTail = null;Node hiHead = null, hiTail = null;Node next;do {next = e.next;if ((e.hashelseloTail.next = e;loTail = e;}else {if (hiTail == null)hiHead = e;elsehiTail.next = e;hiTail = e;}} while ((e = next) != null);if (loTail != null) {loTail.next = null;newTab[j] = loHead;}if (hiTail != null) {hiTail.next = null;newTab[j + oldCap] = hiHead;}}}}}//返回扩容后的hashMapreturn newTab;}删除元素:remove()方法public V remove(Object key) {//临时变量Node e;/**调用removeNode(hash(key), key, null, false, true)进行删除 , 第三个value为null , 表示 , 把key的节点直接都删除了 , 不需要用到值 , 如果设为值 , 则还需要去进行查找操作**/return (e = removeNode(hash(key), key, null, false, true)) == null ?null : e.value;}/**第一参数为哈希值 , 第二个为key , 第三个value , 第四个为是为true的话 , 则表示删除它key对应的value , 不删除key,第四个如果为false , 则表示删除后 , 不移动节点**/final Node removeNode(int hash, Object key, Object value,boolean matchValue, boolean movable) {//tab 哈希数组 , p 数组下标的节点 , n 长度 , index 当前数组下标Node[] tab; Node p; int n, index;//哈希数组不为null , 且长度大于0 , 然后获得到要删除key的节点所在是数组下标位置if ((tab = table) != nullK k; V v;//如果数组下标的节点正好是要删除的节点 , 把值赋给临时变量nodeif (p.hash == hash//也就是要删除的节点 , 在链表或者红黑树上 , 先判断是否为红黑树的节点else if ((e = p.next) != null) {if (p instanceof TreeNode)//遍历红黑树 , 找到该节点并返回node = ((TreeNode)p).getTreeNode(hash, key);else { //表示为链表节点 , 一样的遍历找到该节点do {if (e.hash == hashbreak;}/**注意 , 如果进入了链表中的遍历 , 那么此处的p不再是数组下标的节点 , 而是要删除结点的上一个结点**/p = e;} while ((e = e.next) != null);}}//找到要删除的节点后 , 判断!matchValue , 我们正常的remove删除 , !matchValue都为trueif (node != null//如果是链表结构 , 且删除的节点为数组下标节点 , 也就是头结点 , 直接让下一个作为头else if (node == p)tab[index] = node.next;else /**为链表结构 , 删除的节点在链表中 , 把要删除的下一个结点设为上一个结点的下一个节点**/p.next = node.next;//修改计数器++modCount;//长度减一--size;/**此方法在hashMap中是为了让子类去实现 , 主要是对删除结点后的链表关系进行处理**/afterNodeRemoval(node);//返回删除的节点return node;}}//返回null则表示没有该节点 , 删除失败return null;}


推荐阅读