千家信息网

HashMap底层源码是什么

发表于:2024-11-19 作者:千家信息网编辑
千家信息网最后更新 2024年11月19日,本篇内容介绍了"HashMap底层源码是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! fi
千家信息网最后更新 2024年11月19日HashMap底层源码是什么

本篇内容介绍了"HashMap底层源码是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

   final V putVal(int hash, K key, V value, boolean onlyIfAbsent,                  boolean evict) {       // tab:Node数组       // p:Node节点       // n:Node数组的总长度       // i:当前节点的下标       Node[] tab; Node p; int n, i;       // 判断Node数组是否为空,如果为空并且数组长度为0,则对Node数组进行初始化       if ((tab = table) == null || (n = tab.length) == 0)           n = (tab = resize()).length;       // 对Hash值进行位与运算,赋值给i,得出该key所在的数组下标       // 如果tab[i]是空的,那么新建一个Node并存入数组       if ((p = tab[i = (n - 1) & hash]) == null)           tab[i] = newNode(hash, key, value, null);       // 以上情况都不是       else {                // e: 需要修改的节点                // k: 节点的key值           Node e; K k;           // 判断Node数组饿的第一个节点的Hash值是不是和Hash一致,并且在Hash一致的情况下,           // 两者的Key是否一致,一直的话,将需要修改的节点变为当前节点           if (p.hash == hash &&               ((k = p.key) == key || (key != null && key.equals(k))))               e = p;           // 如果P节点是树节点, 将使用红黑树的形式存储e节点           else if (p instanceof TreeNode)               e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);           // 如果是普通节点           else {               for (int binCount = 0; ; ++binCount) {                        // 如果遍历到最后一个节点,新建Node存储数据                        // 判断他的长度是否大于链表设定长度                        // 如果大于设定长度,则将链表转换为红黑树                   if ((e = p.next) == null) {                       p.next = newNode(hash, key, value, null);                       if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st                           treeifyBin(tab, hash);                       break;                   }                   // 遍历的节点如果Hash值一致,key值也一致,则跳出循环                   if (e.hash == hash &&                       ((k = e.key) == key || (key != null && key.equals(k))))                       break;                   p = e;               }           }           // 如果e不为空 如果onlyIfAbsent参数(覆盖更新)           // 设置为true或者e的Value是null           // 将e的Value修改为传入的Value           // * afterNodeAccess为LinkedHashMap函数,在HashMap中没有进行任何操作           if (e != null) { // existing mapping for key               V oldValue = e.value;               if (!onlyIfAbsent || oldValue == null)                   e.value = value;               afterNodeAccess(e);               return oldValue;           }       }       ++modCount;       // 如果HashMap的总长度大于设定长度,就进行resize操作       if (++size > threshold)           resize();       // * afterNodeInsertion为LinkedHashMap函数,在HashMap中没有进行任何操作       afterNodeInsertion(evict);       return null;   }
    // 对table进行初始化或者两倍扩容    final Node[] resize() {        // oldTab: 数据        // oldCap: 老容量(原Node数组长度)        // oldThr: 老阀值(总数据量大于阀值则扩容)        // newCap, newThr: 新容量和新阀值        Node[] oldTab = table;        int oldCap = (oldTab == null) ? 0 : oldTab.length;        int oldThr = threshold;        int newCap, newThr = 0;        // 如果oldCap大于0        if (oldCap > 0) {            // oldCap >= 最大的容量(1073741824)            // 将全局的阀值修改为最大的Integer(2147483647)            if (oldCap >= MAXIMUM_CAPACITY) {                threshold = Integer.MAX_VALUE;                return oldTab;            }            // 解释一下 newCap = oldCap << 1 和            // newCap = oldCap * 2的结果是一样,            // 如果newCap < 最大容量 并且 oldCap >= 默认初始化容量(16)            // 那么 newThr = oldThr * 2            else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&                     oldCap >= DEFAULT_INITIAL_CAPACITY)                newThr = oldThr << 1;        }        // 如果oldThr大于0        else if (oldThr > 0)            // newCap = oldThr            newCap = oldThr;        // 以上情况都不是        else {               // zero initial threshold signifies using defaults            // newCap = 默认初始化容量            // newThr = 默认负载因子 * 默认初始化容量            newCap = DEFAULT_INITIAL_CAPACITY;            newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);        }        // 如果newThr 为0        if (newThr == 0) {            // ft: 新的负载数量            // ft = newCap * 负载因子            float ft = (float)newCap * loadFactor;            // 如果newCap < 最大容量 && ft < 最大容量            // 那么 newThr = (int) ft            // 否则 newThr = 最大Integer值            newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?                      (int)ft : Integer.MAX_VALUE);        }        // 全局的阀值修改        threshold = newThr;        @SuppressWarnings({"rawtypes","unchecked"})        Node[] newTab = (Node[])new Node[newCap];        table = newTab;        if (oldTab != null) {            for (int j = 0; j < oldCap; ++j) {                Node 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)e).split(this, newTab, j, oldCap);                    else { // preserve order                        Node loHead = null, loTail = null;                        Node hiHead = null, hiTail = null;                        Node next;                        do {                            next = e.next;                            if ((e.hash & oldCap) == 0) {                                if (loTail == null)                                    loHead = e;                                else                                    loTail.next = e;                                loTail = e;                            }                            else {                                if (hiTail == null)                                    hiHead = e;                                else                                    hiTail.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;                        }                    }                }            }        }        return newTab;    }

"HashMap底层源码是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0