HASHMAP RESIZE() 单链表复制

    Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
table = newTab;
if (oldTab != null) {
    for (int j = 0; j < oldCap; ++j) {
        Node<K,V> e;
        if ((e = oldTab[j]) != null) {
            oldTab[j] = null;
            if (e.next == null)       //说明单链表只有一个节点 直接复制
                newTab[e.hash & (newCap - 1)] = e;
            else if (e instanceof TreeNode)   //红黑树复制
                ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
            else { // preserve order    //单链表多节点    复制
                Node<K,V> loHead = null, loTail = null;//代表原数组长度(16)以内的位置
                Node<K,V> hiHead = null, hiTail = null;//扩容后大于原数组长度的位置
                Node<K,V> next;
                do {
                    next = e.next;
                    if ((e.hash & oldCap) == 0) {    //代表不需要改变位置的元素
                        if (loTail == null)
                            loHead = e;
                        else
                            loTail.next = e;    //第二次进来的节点直接next
                        loTail = e;
                    }
                    else {                //代表需要改变位置的元素
                        if (hiTail == null)
                            hiHead = e;
                        else
                            hiTail.next = e;       //节点复制 直接next 
                        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;   //新数组中 扩容部分的位置 元素赋值
                }
            }
        }
    }
}

小结:

1. 总共三个情况 (hashmap 扩容 原数据复制) 

a. 单链表只有一个节点复制 b. 红黑树复制 c. 单链表多节点复制

2. 需要改变位置的节点并没有重新计算数组下标 而是直接采用 原数组下标+原数组长度




阅读更多
文章标签: HASHMAP
个人分类: 技术 代码考究
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭