城市直播房产教育博客汽车
投稿投诉
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

HashMap底层实现原理

6月2日 不将就投稿
  HashMap采用NodeK,V数组来存储keyvalue对,每一个键值对组成了一个Node实体,Node类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个Node实体。HashMap在JDK1。8之前和之后的区别
  JDK1。8之前,数组链表存储结构
  缺点就是哈希函数很难使元素百分百的均匀分布,这会产生一种极端的可能,就是大量的元素存在一个桶里
  JDK1。8之后:数组链表红黑树添加元素时:链表长度大于8的时候,转换为红黑树删除元素、扩容时,同上,数量大于8时,也是采用红黑树形式存储,但是在数量较少时,即数量小于6时,会将红黑树转换回链表遍历、查找时,使用红黑树,他的时间复杂度O(logn),便于性能的提高。数据结构
  存储结构
  staticclassNodeK,VimplementsMap。EntryK,V{finalKVNodeK,VNode(inthash,Kkey,Vvalue,NodeK,Vnext){this。this。this。this。}publicfinalKgetKey(){}publicfinalVgetValue(){}publicfinalStringtoString(){}publicfinalinthashCode(){returnObjects。hashCode(key)Objects。hashCode(value);}publicfinalVsetValue(VnewValue){VoldVvaluenewVreturnoldV}publicfinalbooleanequals(Objecto){if(othis)if(oinstanceofMap。Entry){Map。E?,?e(Map。E?,?)o;if(Objects。equals(key,e。getKey())Objects。equals(value,e。getValue()))}}}
  NodeK,V数组transientNodeK,V〔〕加载因子finalfloatloadF默认加载因子,容量达到这个比例时自动扩容staticfinalfloatDEFAULTLOADFACTOR0。75f;数量大于8时,链表转换为红黑树形式存储staticfinalintTREEIFYTHRESHOLD8;即数量小于6时,会将红黑树转换回链表,删除元素时removestaticfinalintUNTREEIFYTHRESHOLD6;PUT时每次都做hashpublicVput(Kkey,Vvalue){returnputVal(hash(key),key,value,false,true);}put函数核心算法finalVputVal(inthash,Kkey,Vvalue,booleanonlyIfAbsent,booleanevict){NodeK,V〔〕NodeK,Vp;intn,i;if((tabtable)null(ntab。length)0)n(tabresize())。if((ptab〔i(n1)hash〕)null)这里的n表示数组的长度。hashtab〔i〕newNode(hash,key,value,null);else{NodeK,Ve;Kk;if(p。hashhash((kp。key)key(key!nullkey。equals(k))))elseif(pinstanceofTreeNode)e((TreeNodeK,V)p)。putTreeVal(this,tab,hash,key,value);else{for(intbinCount0;;binCount){if((ep。next)null){p。nextnewNode(hash,key,value,null);if(binCountTREEIFYTHRESHOLD1)1for1sttreeifyBin(tab,hash);}if(e。hashhash((ke。key)key(key!nullkey。equals(k))))}}if(e!null){existingmappingforkeyVoldValuee。if(!onlyIfAbsentoldValuenull)e。afterNodeAccess(e);空实现returnoldV}}modCmodCount是java集合中FailFast的底层实现原理if(sizethreshold)扩容resize();afterNodeInsertion(evict);空实现}CallbackstoallowLinkedHashMappostactionsvoidafterNodeAccess(NodeK,Vp){}voidafterNodeInsertion(booleanevict){}voidafterNodeRemoval(NodeK,Vp){}思考
  java集合中的快速失败:modCount
  快速失败是Java集合的一种错误检测机制,当多个线程对集合进行结构上的改变的操作时,有可能会产生failfast。
  举个例子:假设存在两个线程(线程1、线程2),线程1通过Iterator在遍历集合A中的元素,在某个时候线程2修改了集合A的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就可能会抛出ConcurrentModificationException异常,从而产生fastfail快速失败。
  HashMap中遍历算法如下:finalclassKeySetextendsAbstractSetK{publicfinalintsize(){}publicfinalvoidclear(){HashMap。this。clear();}publicfinalIteratorKiterator(){returnnewKeyIterator();}publicfinalbooleancontains(Objecto){returncontainsKey(o);}publicfinalbooleanremove(Objectkey){returnremoveNode(hash(key),key,null,false,true)!}publicfinalSpliteratorKspliterator(){returnnewKeySpliterator(HashMap。this,0,1,0,0);}publicfinalvoidforEach(C?superKaction){NodeK,V〔〕if(actionnull)thrownewNullPointerException();if(size0(tabtable)!null){intmcmodCfor(inti0;itab。i){for(NodeK,Vetab〔i〕;e!ee。next)action。accept(e。key);}if(modCount!mc)抛出异常,FailFastthrownewConcurrentModificationException();}}}优化hash算法
  JDK1。8中,是通过hashCode()的高16位异或低16位实现的:(hk。hashCode())(h16),主要是从速度,功效和质量来考虑的,减少系统的开销,也不会造成因为高位没有参与下标的计算,从而引起的碰撞。扰动函数:促使元素位置分布均匀,减少碰撞几率staticfinalinthash(Objectkey){如果keynull返回的值是0如果key!null首先计算key的hashcode值赋值给h,然后与h无符号右移16位后的二进制按位异或预算得到最后hash值return(keynull)?0:(hkey。hashCode())(h16);}hash具体实现过程如下图所示:
  hash计算过程与putval函数的应用key。hashCode();返回散列值也就是hashcode,假设随便生成的一个值。n表示数组初始化的长度是16。(按位与运算):运算规则:相同的二进制数位上,都是1的时候,结果为1,否则为零。(按位异或运算):运算规则:相同的二进制数位上,数字相同,结果为0,不同为1。
  高16bit不变,低16bit和高16bit做了一个异或(得到的hashCode转化为32位二进制,前16位和后16位低16bit和高16bit做了一个异或)为什么这样实现呢?
  如果当n即数组长度很小,假设是16的话,那么n1即为1111,这样的值和hashCode直接做按位与操作,实际上只使用了哈希值的后4位。如果当哈希值的高位变化很大,低位变化很小,这样就很容易造成哈希冲突了,所以这里把高低位都利用起来,从而解决了这个问题。降低了Hash冲突的概率为什么要用异或运算符
  保证了对象的hashCode的32位值只要有一位发生改变,整个hash()返回值就会改变。尽可能的减少碰撞。
  工作原理
  存储对象时,将KV键值传给put()方法:调用hash(K)方法计算K的hash值,然后结合数组长度,计算得数组下标;调整数组大小(当容器中的元素个数大于capacityloadfactor时,容器会进行扩容resize为2n);hash碰撞
  i。如果K的hash值在HashMap中不存在,则执行插入,若存在,则发生碰撞;
  ii。如果K的hash值在HashMap中存在,且它们两者equals返回true,则更新键值对;
  iii。如果K的hash值在HashMap中存在,且它们两者equals返回false,则插入链表的尾部(尾插法)或者红黑树中(树的添加方式)。(JDK1。7之前使用头插法、JDK1。8使用尾插法)
  get实现publicVget(Objectkey){NodeK,Ve;return(egetNode(hash(key),key))null?null:e。}ImplementsMap。getandrelatedmethodsparamhashhashforkeyparamkeythekeyreturnthenode,ornullifnonefinalNodeK,VgetNode(inthash,Objectkey){NodeK,V〔〕NodeK,Vfirst,e;Kk;if((tabtable)!null(ntab。length)0(firsttab〔(n1)hash〕)!null){if(first。hashhashalwayscheckfirstnode((kfirst。key)key(key!nullkey。equals(k))))if((efirst。next)!null){if(firstinstanceofTreeNode)return((TreeNodeK,V)first)。getTreeNode(hash,key);do{if(e。hashhash((ke。key)key(key!nullkey。equals(k))))}while((ee。next)!null);}}}
  问题思考?
  Q:默认初始化大小是多少?为啥是这么多?为啥大小都是2的幂?
  A:hash运算的过程其实就是对目标元素的Key进行hashcode,再对Map的容量进行取模,而JDK的工程师为了提升取模的效率,使用位运算代替了取模运算,这就要求Map的容量一定得是2的幂。HashMap的容量为什么是2的n次幂,和这个putval方法中(n1)hash的计算方法有着千丝万缕的关系,符号是按位与的计算,这是位运算,计算机能直接运算,特别高效,按位与的计算方法是,只有当对应位置的数据都为1时,运算结果也为1,当HashMap的容量是2的n次幂时,(n1)的2进制也就是1111111111这样形式的,这样与添加元素的hash值进行位运算时,能够(充分的散列),使得添加的元素均匀分布在HashMap的每个位置上,减少hash碰撞。
  Q:HashMap如何有效减少碰撞?
  A:扰动函数:促使元素位置分布均匀,减少碰撞几率、使用final对象,并采用合适的equals()和hashCode()方法
投诉 评论 转载

比变老更可怕的是选错上衣,夏天建议上衣多选白色,得体还显年轻在很多人眼中,变老是女人最害怕的事情,似乎只要变老,女人的魅力就会荡然无存。事实却非如此,变老并不可怕,对于上了年纪的女人,破罐子破摔、认老、不修边幅才最可怕,特别是在挑选上衣……HashMap底层实现原理HashMap采用NodeK,V数组来存储keyvalue对,每一个键值对组成了一个Node实体,Node类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个Nod……亚马逊何时走出至暗时刻?头条创作挑战赛来源东哥解读电商文金珊今年亚马逊的日子并不好过。先是官宣停止招聘,随即在黑五大促前,进行了史上最大规模的裁员,人数近一万人,包括核心零售、人力资……昆明西山千步岩,一个小众的景点,树林茂密,全程古道,适合爬山一般昆明人爬西山,都喜欢从西山脚底高峣的正大门,穿过茶马花街,徒步前行。曾经西山的入口,现在变成了美食街。而我今天介绍大家的是一条小路,从这条小路也可以爬到龙门景区……佛子罗睺罗的罗睺寺,唐代的石狮子五台山我们在台怀的第一天,先去菩萨顶(灵鹫峰上菩萨顶,一览台怀诸寺五台山),从菩萨顶下来去罗睺寺。罗睺寺在菩萨顶山下,和塔院寺挨着,是台怀中心地带的主要寺院。路口立有单门木牌坊。……哺乳观察实录成为妈妈后,喂奶真是一大难关亲自母乳喂养,对于这个妈妈来说非常困难,是每个哺乳期母亲都曾经历过最悲伤的崩溃。好不容易生下孩子,却要没日没夜吃喝,帮助补足奶水。一旦心情不好,就会导致奶水走失。炎炎夏季……女排世锦赛开赛荷兰波兰取得开门红新华社荷兰阿纳姆9月23日电(记者刘旸、肖亚卓)2022世界女排锦标赛23日在荷兰东部城市阿纳姆开赛,荷兰队3:0击败肯尼亚队,波兰队3:1战胜克罗地亚队。本届女排世锦赛……探索自动驾驶商业化小马智行与曹操出行吉利智驾中心组建Robo21世纪经济报道记者杜巧梅报道9月22日,小马智行宣布与曹操出行、吉利汽车创新研究院智能驾驶中心达成战略合作。小马智行将利用自身在L4级自动驾驶技术以及Robotaxi运……利物浦欲打造世界级中场两目标球员转会支出超2。5亿欧元据报道,利物浦曾在今年夏天为皇家马德里球星费德里科巴尔韦德提供过一份1亿欧元的报价,明年夏天他们将再次尝试引进这位乌拉圭球星。虽然利物浦没能成功的将巴尔韦德带到安菲尔德,但是在……梦天发射在即的文昌龙楼镇民宿满房,有人清晨占位置看发射作为中国空间站T字构型的最后一个舱段,梦天实验舱即将于今天(10月31日)下午,在海南文昌航天发射场发射升空。目前各系统也完成了相关功能检查,准备就绪。文昌航天发射场所在……遗憾!继张常宁之后,又一女排奥运冠军或也将缺席排超2022至2023赛季中国女排超级联赛即将开战,目前各支球队都已做好准备迎接下赛季排超联赛的开幕,随着联赛即将开始,各支参赛球队也陆续公布了新赛季球队的参赛阵容。在此前江苏女排……恭喜刘诗雯!有望赴ITTF任职新岗位,薪资可观,应该感谢刘国近日有消息称刘诗雯这位优秀的乒乓球运动员即将前往ITTF担任委员的职位,ITTF是国际乒联的缩写,在最近一段时间,国际乒联开始选拔运动员委员会的成员,中国方面刘诗雯和残疾人奥运……
安检光机扫描揭秘为什么李佳琦是第一个叫我不要睡的男人直播抢货还在挂腰风扇口罩风扇夏日降温神器登场在日本,有一种美叫今田美樱表达爱情忧伤的朋友圈说说泡妹子说得话对妹子表白得句子浅析机械模具技术的现状与发展去云南旅游如何防止被骗麦积山雪后初霁美如画卷2022年买手机推荐这三款,几乎没有短板,至少能用三五年何处造句用何处造句大全独角兽的魔力

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找