hashmap源码解读扩容变换关键代码
2021/7/27 22:05:58
本文主要是介绍hashmap源码解读扩容变换关键代码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Map—HashMap源码解析(使用频率最高)
根据韩顺平老师课做的笔记
需要课程去B站收韩顺平
HashMap小结
1)Map接口的常用方法 HashMap HashTable 和Properties
2)HashMap是Map接口使用频率最高的实现类
3)HashMap是以key-val对的方式来存储数据 hashmapnode
4)key不能重复 但是值可以重复允许使用null键和null值
5)如果添加相同的key 则会覆盖原来的key -val 等同修改
6)与HashSet一样不会保证映射的的顺序 因为底层是以hash表的方式来存储的
7)hashMap没有实现同步 因为是线程不安全的
map存储 table
table->node存储
node由entrySet管理
存储还是以key存储为准
输入的值进入hashmap 进行debug 运行过程中 进行源码解析
Map接口实现类 HashMap
1)
HashMap底层机制以及源码解析
HashMap源码开始
HashMap
HashMap底层维护了Node类型的数组table 默认为null
2)当陈篡关键对象时 将加载因子 loadfactor 初始化为0.75
3)当添加key-val时 通过key的hashcode得到table的然后判断该索引出是否含有元素如果没有元素 如果没有元素直接添加 如果该索引处有元素 继续判断该院的key是否和准备加入的key相等 如果相等则直接替换val 如果不相等需要判断时树结构还是链表结构 做出相应处理 如果添加时发现容量不够 则需要扩容
4)第一次添加则需要扩容table为16 临界值为12
5)以后再扩容则需要扩容table容量为原来的2倍 临界值为原来的2倍即24
6)对于一个链表如果一条链表的元素个数超过treeify_threasholp并且table 的大小>=min_treeUFY 64就会进行书画
第一步
1、执行构造器
new HashMap()
初始化加载因子 loadfactor = 0.75
hashmapnode table = null
table 为null
第二步put 调用hash 方法 计算hash方法 计算 key的hash值 (h=keyhashCode())^(h>>>16)
public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
默认初始值是16
看代码中注释
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; //辅助变量 //如果底层table 数组威null 或者 length=0 就扩容到16 if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; //取出hash相对应的table的索引位置的node 如果为null 就直接把加入k-v //创建一个node 加入该位置即可 if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k; //辅助变量 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { for (int binCount = 0; ; ++binCount) { if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }
经过扩容后大小为32 临界值 24
需要自己设计程序 验证-》 增强自己阅读源码的能力看别人代码
这篇关于hashmap源码解读扩容变换关键代码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-20Java全栈教程:从入门到实战
- 2024-11-20Java微服务系统教程:入门与实践指南
- 2024-11-20Less教程:初学者快速上手指南
- 2024-11-20MyBatis教程:新手快速入门指南
- 2024-11-20QLExpress教程:初学者快速入门指南
- 2024-11-20订单系统教程:从入门到实践的全面指南
- 2024-11-20负载均衡教程:新手入门必备指南
- 2024-11-20微信支付教程:新手入门必备指南
- 2024-11-20系统部署教程:轻松入门与实践
- 2024-11-20入门级中间件教程:轻松掌握中间件基础知识