美文网首页java并发学习
HashMap1.8的扩容机制

HashMap1.8的扩容机制

作者: 何甜甜在吗 | 来源:发表于2018-03-15 23:16 被阅读102次

HashMap1.8的扩容机制非常好玩,首先将扩容的代码揪出来

  if (oldTab != null) {
            //oldCap为原数组的长度
            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)
                        //如果是红黑树结构,就调用split
                        ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
                    else { // preserve order
                        //如果数组中存放的是链表,会将原来的链表
                       分成两条链表
                        Node<K,V> loHead =o null, loTail = null;
                        Node<K,V> hiHead = null, hiTail = null;
                        Node<K,V> next;
                        do {
                            next = e.next;
                            //通过计算e.hash&oldCap==0构造一条链
                            if ((e.hash & oldCap) == 0) {
                                if (loTail == null)
                                    loHead = e;
                                else
                                    loTail.next = e;
                                loTail = e;
                            } //通过e.hash&oldCap!=0构造另外一条链
                            else {
                                if (hiTail == null)
                                    hiHead = e;
                                else
                                    hiTail.next = e;
                                hiTail = e;
                            }
                        } while ((e = next) != null);
                        //遍历结束以后,将tail指针指向null
                       //e.hash&oldCap==0构造而来的链的位置不变
                        if (loTail != null) {
                            loTail.next = null;
                            newTab[j] = loHead;
                        }
                       //e.hash&oldCap!=0构造而来的链的位置在数
                      //组j+oldCap位置处
                        if (hiTail != null) {
                            hiTail.next = null;
                            newTab[j + oldCap] = hiHead;
                        }
                    }
                }
            }
        }

这里暂时只介绍链表,红黑树结构暂时还只了解概念
为什么说扩容机制很好玩呢,因为它会将原来的链表同过计算e.hash&oldCap==0分成两条链表,再将两条链表散列到新数组的不同位置上

上张图:生动形象


hashmap扩容

扩容前数组长度为8,扩容为原数组长度的2倍即16。
原来有一条链表在tab[2]的位置,扩容以后仍然有一条链在tab[2]的位置,另外一条链在tab[2+8]即tab[10]的位置处。

多线程情况,对hashmap进行put操作会引起resize,并可能会造成数组元素的丢失

相关文章

网友评论

  • Boykazz:为什么不是newCap 而是oldCap?
    ac77d32e047f:你要将旧的map扩容到新的map,当然是循环旧的

本文标题:HashMap1.8的扩容机制

本文链接:https://www.haomeiwen.com/subject/pcukqftx.html