博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HashMap详解(一). put方法详解
阅读量:6074 次
发布时间:2019-06-20

本文共 2896 字,大约阅读时间需要 9 分钟。

hot3.png

JAVA8

1.HashMap.put 方法实现了Map.put(K key,V value)的方法。直接调用内部方法

205339_xwUM_2341924.png

大致思路是这样的:

  1. 对key的hashCode()进行hash后计算数组下标index;
  2. 如果当前数组table为null,进行resize()初始化;
  3. 如果没碰撞直接放到对应下标的bucket里;
  4. 如果碰撞了,且节点已经存在,就替换掉 value;
  5. 如果碰撞后发现为树结构,挂载到树上。
  6. 如果碰撞后为链表,添加到链表尾,并判断链表如果过长(大于等于TREEIFY_THRESHOLD,默认8),就把链表转换成树结构;
  7. 数据 put 后,如果数据量超过threshold,就要resize。

下面是putVal方法解析

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,                   boolean evict) {        Node
[] tab; Node
p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) //首次放入元素时,分配table空间-默认size=16 n = (tab = resize()).length; if ((p = tab[i = (n - 1) & hash]) == null) // 算出新node在table中的位置,若对应位置为null,新建一个node并放入对应位置. // 注意: (n - 1) & hash 求余操作 等价于 hash%n(只有n为2的幂时才成立,见下图) tab[i] = newNode(hash, key, value, null); else { //在table对应位置有node时 Node
e; K k; if (p.hash == hash && // key一样 (hash值相同,且key 一样,相同实例或者满足Object.equals方法) ((k = p.key) == key || (key != null && key.equals(k)))) // 不满足此条件则发生hash碰撞 e = p; else if (p instanceof TreeNode) // hash碰撞的情况下,用链表解决,链表大于8时,改为红黑树. 当node为treeNode时,putTreeVal->红黑树 e = ((TreeNode
)p).putTreeVal(this, tab, hash, key, value); else { //hash for (int binCount = 0; ; ++binCount) { //用for循环将链表指针后移,将新node在链表加在尾部 if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // 当链表长度大于8时,转成红黑树 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) //当node中旧的值null或者onlyIfAbsent==false时,将新的value替换原来的value. e.value = value; afterNodeAccess(e); //新node塞入table后做的做的事情,在HashMap中是一个空方法(LinkedHashMap中有有使用, move node to last) return oldValue; } } ++modCount; if (++size > threshold) //新的size大于阈值(默认0.75*table.length)时,扩容. resize(); afterNodeInsertion(evict); return null; }

 

235450_YihJ_2341924.png

总结.

1.第一次put操作时,才为table分配内存空间,

2.当发生hash碰撞时,先链表,链表长度大于8时,转为红黑树.

 

转载于:https://my.oschina.net/u/2341924/blog/1560149

你可能感兴趣的文章
微商怎么引流客源,谈谈我这些年引流的经验
查看>>
运算符==和Equals()的总结
查看>>
艾伟:Silverlight 2应用程序中XAP文件揭秘
查看>>
Asio学习1: TCP客户端:对准时间 解析
查看>>
jQuery之万能的选择器
查看>>
(android 地图实战开发)2 创建MapActivity,根据设备当前位置,显示地图
查看>>
了解电子邮件加密 保证隐私内容安全
查看>>
史上最恶毒10大病毒 Conficker排名第八
查看>>
Win7 配“.NET研究”置Android开发环境
查看>>
【Perl】模块 Tie::File
查看>>
NHibernate初学者指南(2):一个完整的例子
查看>>
Jenkins最佳实践
查看>>
SQL Server 2005 性能优化实战系列(文章索引)
查看>>
cocos2d-x的未来展望
查看>>
Mybatis3 generator的使用附demo 及sqlserver 分页插件
查看>>
rsh+rlogin+ssh+scp
查看>>
利用指针方法object_getInstanceVariable()获取私有变量的值
查看>>
C#后台调用前台javascript的五种方法小结
查看>>
MS CRM 2011的自定义与开发(12)——表单脚本扩展开发(2)
查看>>
单射、双射与满射
查看>>