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底层源码是什么"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!
节点
数组
容量
长度
最大
一致
情况
数据
底层
源码
下标
全局
内容
函数
因子
更多
知识
存储
实用
普通
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
闲置电脑做服务器练习
计算机 学习网络技术
成都企业软件开发免费完整版
如何实现教学软件开发
嘉兴软件开发班
国内服务器产品
西安凯瑞软件开发有限公司
网络安全相关法律是什么
时序数据库的书
网络技术点对点
公安网络安全体会
swift 数据库
网络安全法变化
我的世界服务器地形名称
直销人用的软件开发
自己创建软件开发团队
舆论 网络安全
开软件开发门店
iptv网络安全分析
网络安全面试题及答案
网络安全设备未配置使用
考研北京邮电大学网络安全多少分
dsm 数据库打不开
数据库三级模式对应数据库的
惠普服务器u盘启动
打开数据库时ora01034
长宁区参考网络技术服务哪家好
网络安全龙头股有哪些
盐城网络技术开发公司招聘
联网服务器