HashMap底层源码是什么
发表于:2025-02-20 作者:千家信息网编辑
千家信息网最后更新 2025年02月20日,本篇内容介绍了"HashMap底层源码是什么"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! fi
千家信息网最后更新 2025年02月20日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底层源码是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
节点
数组
容量
长度
最大
一致
情况
数据
底层
源码
下标
全局
内容
函数
因子
更多
知识
存储
实用
普通
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
超算服务器的组成
阿里云服务器搭建lnmp
软件开发专注熊掌网络
虹膜数据库视频
私有服务器厂商
如何使用数据库找不到存储文件
网络安全工程师培训全套
安卓开发需要学数据库吗
数据库个案信息如何删除
为什么服务器总是在维护中
哈工大网络安全ppt
香港奇门遁甲软件开发
广州民宿宝互联网科技有限公司
电驴服务器禁用
人民网络安全专项整治
诺亚方舟网络技术有限公司
关系型数据库经验证明
壹零新蜂网络技术有限公司
评标在线管理服务器
高中网络安全内容
四数据库提取基因cdca5
山西pdu服务器电源销售价格
湖北省委网络安全会议
将mysql数据库改为utf8
linux删除数据库表命令
运营商异地网络技术
山东电商软件开发价格表
中国电子网络安全ppt
狂野飙车8服务器在哪
网络安全软件挣钱行业