前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试题-JAVA之HashMap-get、resize方法源码分析

面试题-JAVA之HashMap-get、resize方法源码分析

作者头像
别明天就今天吧
发布2020-09-07 01:05:27
4340
发布2020-09-07 01:05:27
举报
文章被收录于专栏:别明天就今天吧

HashMap的get方法是通过key获取对应Value的方法,resize方法则是初始化或扩容数组的方法,来看看是如何实现的;

1.get方法

通过getNode方法传入key的hash值与key,判断返回是否为空,空则返回null,否则返回key对应的value值;

方法中第一个if判断数组是否为空、数组长度是否大于0,并且通过(n-1)&hash计算出的下标在数组中是否存在元素,满足以上条件则,进入第二个if判断,拿到下标所在的元素的hash值与传入的hash值进行比较,如果相等并且key值也相等,则命中元素直接返回;如果没有命中,则进入下一个if判断看下标元素的next是否有值,如果有判断当前元素是否为红黑树,如果为红黑树则通过hash值、key值在树中获取元素返回;否则就是链表,然后循环链表,直到hash与key都相等则命中,否则返回null;

2.resize方法

resize方法的作用是扩容,方法较长我们分前后两个部分进行分析,前半部分比较简单,首先看定义的这几个变量,oldCap:老容量,oldThr:老阈值,newCap:新容量,newThr:新阈值,oldTable就是当前的数组;然后第一个if判断,oldCap是否大于0,大于0说明是扩容,否则说明数组第一次初始化容量,满足条件进入内部判断容量是否大于等于最大容量,满足条件则给阈值赋值为最大int,然后返回;否则老容量扩大二倍赋值给新容量,老阈值扩大2倍给新阈值;

这显然是初始化的时候,赋值新容量为16,新阈值为16*0.75=12;

创建一个大小为新容量的Node数组并赋值给数组,这时候并发查询会出问题;

这段代码主要是遍历老的数组,判断元素类型是普通Node、链表、红黑树,如果是普通Node元素则通过hash&(newCap-1)计算出新下标并赋值,如果是红黑树解析赋值给新数组;如果是链表,则根据hash&oldCap的算法区分是高位还是低位,如果是低位下标不变,如果不为0则说明hash值大于老数组长度,应该放到高位上;

第一个判断说明低位的元素链表还放到原来的位置,第二个判断说明高位的元素放在原有位置偏移了老数组长度的位置;

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 别明天就今天吧 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档