纠纷奇闻作文社交美文家庭
聚热点
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

你要的hashMap解读来了

1月17日 囍孤女投稿
  最近快到金三银四了,不少小伙伴又开始忙忙碌碌找工作了,我也是,秉着为自己也为大家,整理了下hashMap的知识点,希望能对你有所帮助!
  这里主要是对jdk1。7和jdk1。8的分析JDK1。7hashMap结构图
  img1。7hashMap变量初始容量16负载因子0。75数组节点类型是EntryK,Vput函数过程publicVput(Kkey,Vvalue){容量为空则初始化if(tableEMPTYTABLE){inflateTable(threshold);}key为null则进行putkey为null的操作if(keynull)returnputForNullKey(value);求hash值根据hashCode再进行一些位运算降低hash冲突的概率inthashhash(key);根据元素hash值求索引intiindexFor(hash,table。length);for(EntryK,Vetable〔i〕;e!ee。next){O如果元素hash值和key都和桶上的第一个元素相同,则替换valueif(e。hashhash((ke。key)keykey。equals(k))){VoldValuee。e。e。recordAccess(this);returnoldV}}modC添加元素头插法(可能会造成死循环)addEntry(hash,key,value,i);}hash函数过程hash冲突的解决办法:
  开放定址法
  再哈希法
  链地址法(拉链法,hashMap使用)Retrieveobjecthashcodeandappliesasupplementalhashfunctiontotheresulthash,whichdefendsagainstpoorqualityhashfunctions。ThisiscriticalbecauseHashMapusespoweroftwolengthhashtables,thatotherwiseencountercollisionsforhashCodesthatdonotdifferinlowerbits。Note:Nullkeysalwaysmaptohash0,thusindex0。finalinthash(Objectk){inthhashSif(0!hkinstanceofString){returnsun。misc。Hashing。stringHash32((String)k);}hk。hashCode();ThisfunctionensuresthathashCodesthatdifferonlybyconstantmultiplesateachbitpositionhaveaboundednumberofcollisions(approximately8atdefaultloadfactor)。h(h20)(h12);returnh(h7)(h4);}求索引位置indexFor函数jdk1。7求索引位置函数staticintindexFor(inth,intlength){assertInteger。bitCount(length)1:lengthmustbeanonzeropowerof2;returnh(length1);}扩容过程1。addEntry函数Addsanewentrywiththespecifiedkey,valueandhashcodetothespecifiedbucket。Itistheresponsibilityofthismethodtoresizethetableifappropriate。添加元素Subclassoverridesthistoalterthebehaviorofputmethod。voidaddEntry(inthash,Kkey,Vvalue,intbucketIndex){当前容量大于等于负载数且当前位置首个元素不为空if((sizethreshold)(null!table〔bucketIndex〕)){扩容为原来的两倍resize(2table。length);hash(null!key)?hash(key):0;bucketIndexindexFor(hash,table。length);}createEntry(hash,key,value,bucketIndex);}2。resize函数Rehashesthecontentsofthismapintoanewarraywithalargercapacity。Thismethodiscalledautomaticallywhenthenumberofkeysinthismapreachesitsthreshold。IfcurrentcapacityisMAXIMUMCAPACITY,thismethoddoesnotresizethemap,butsetsthresholdtoInteger。MAXVALUE。Thishastheeffectofpreventingfuturecalls。paramnewCapacitythenewcapacity,MUSTmustbegreaterthancurrentcapacityunlesscurrentcapacityisMAXIMUMCAPACITY(inwhichcasevalueisirrelevant)。voidresize(intnewCapacity){Entry〔〕oldTintoldCapacityoldTable。if(oldCapacityMAXIMUMCAPACITY){thresholdInteger。MAXVALUE;}创建新数组Entry〔〕newTablenewEntry〔newCapacity〕;元素重新求索引位置元素从旧数组移到新数组上transfer(newTable,initHashSeedAsNeeded(newCapacity));tablenewT设置新的负载数threshold(int)Math。min(newCapacityloadFactor,MAXIMUMCAPACITY1);}TransfersallentriesfromcurrenttabletonewTable。voidtransfer(Entry〔〕newTable,booleanrehash){intnewCapacitynewTable。for(EntryK,Ve:table){while(null!e){EntryK,Vnexte。if(rehash){e。hashnulle。key?0:hash(e。key);}intiindexFor(e。hash,newCapacity);e。nextnewTable〔i〕;newTable〔i〕e;}}}移除Removesthemappingforthespecifiedkeyfromthismapifpresent。paramkeykeywhosemappingistoberemovedfromthemapreturnthepreviousvalueassociatedwithttkeytt,orttnullttiftherewasnomappingforttkeytt。(Attnullttreturncanalsoindicatethatthemappreviouslyassociatedttnullttwithttkeytt。)publicVremove(Objectkey){移除key对应的元素并返回entryEntryK,VeremoveEntryForKey(key);return(enull?null:e。value);}RemovesandreturnstheentryassociatedwiththespecifiedkeyintheHashMap。ReturnsnulliftheHashMapcontainsnomappingforthiskey。finalEntryK,VremoveEntryForKey(Objectkey){if(size0){}inthash(keynull)?0:hash(key);根据元素hash值求索引intiindexFor(hash,table。length);桶的首个节点EntryK,Vprevtable〔i〕;EntryK,Vwhile(e!null){EntryK,Vnexte。O判断元素是否和移除的元素key和hash值相同,相同则进行移除操作if(e。hashhash((ke。key)key(key!nullkey。equals(k)))){modC如果桶的首个元素和被移除的元素相同则将next置为桶的首个元素if(preve)table〔i〕elseprev。e。recordRemoval(this);}}}get函数(根据key获取entry)publicVget(Objectkey){if(keynull)returngetForNullKey();EntryK,VentrygetEntry(key);returnnullentry?null:entry。getValue();}finalEntryK,VgetEntry(Objectkey){if(size0){}inthash(keynull)?0:hash(key);遍历索引上的链表for(EntryK,Vetable〔indexFor(hash,table。length)〕;e!ee。next){Ohash值相同key也相等则返回entry元素if(e。hashhash((ke。key)key(key!nullkey。equals(k))))}}缩容
  无JDK1。8hashMap1。8hashMap变量初始容量16负载因子0。75数组节点类型是NodeK,VTREEIFYTHRESHOLD链表节点数大于TREEIFYTHRESHOLD转变为红黑树image20230202205319483put函数过程ImplementsMap。putandrelatedmethods。paramhashhashforkeyparamkeythekeyparamvaluethevaluetoputparamonlyIfAbsentiftrue,dontchangeexistingvalueparamevictiffalse,thetableisincreationmode。returnpreviousvalue,ornullifnonefinalVputVal(inthash,Kkey,Vvalue,booleanonlyIfAbsent,booleanevict){NodeK,V〔〕NodeK,Vp;intn,i;数组为空或长度为0初始化数组if((tabtable)null(ntab。length)0)n(tabresize())。索引位置的桶为空创建节点if((ptab〔i(n1)hash〕)null)tab〔i〕newNode(hash,key,value,null);else{NodeK,Ve;Kk;如果put的元素为桶的首个节点,e赋值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);链表长度大于TREEIFYTHRESHOLD链表转红黑树if(binCountTREEIFYTHRESHOLD1)1for1sttreeifyBin(tab,hash);}if(e。hashhash((ke。key)key(key!nullkey。equals(k))))}}统一处理,value值if(e!null){existingmappingforkeyVoldValuee。if(!onlyIfAbsentoldValuenull)e。afterNodeAccess(e);returnoldV}}modCsize大于负载容量时,扩容if(sizethreshold)扩容resize();afterNodeInsertion(evict);}hash函數staticfinalinthash(Objectkey){hashCode值与hashCode值右移16位做异或得出来的值高低位特征都有保留扰动效果更好return(keynull)?0:(hkey。hashCode())(h16);}扩容过程函数resizefinalNodeK,V〔〕resize(){NodeK,V〔〕oldTintoldCap(oldTabnull)?0:oldTab。intoldTintnewCap,newThr0;if(oldCap0){if(oldCapMAXIMUMCAPACITY){thresholdInteger。MAXVALUE;returnoldT}elseif((newCapoldCap1)MAXIMUMCAPACITYoldCapDEFAULTINITIALCAPACITY)newThroldThr1;doublethreshold}elseif(oldThr0)initialcapacitywasplacedinthresholdnewCapoldTelse{zeroinitialthresholdsignifiesusingdefaultsnewCapDEFAULTINITIALCAPACITY;newThr(int)(DEFAULTLOADFACTORDEFAULTINITIALCAPACITY);}if(newThr0){floatft(float)newCaploadFnewThr(newCapMAXIMUMCAPACITYft(float)MAXIMUMCAPACITY?(int)ft:Integer。MAXVALUE);}thresholdnewTSuppressWarnings({rawtypes,unchecked})NodeK,V〔〕newTab(NodeK,V〔〕)newNode〔newCap〕;tablenewTif(oldTab!null){for(intj0;joldCj){NodeK,Ve;if((eoldTab〔j〕)!null){oldTab〔j〕if(e。nextnull)newTab〔e。hash(newCap1)〕e;elseif(einstanceofTreeNode)((TreeNodeK,V)e)。split(this,newTab,j,oldCap);else{preserveorderNodeK,VloHeadnull,loTNodeK,VhiHeadnull,hiTNodeK,Vdo{nexte。if((e。hasholdCap)0){if(loTailnull)loHelseloTail。loT}else{if(hiTailnull)hiHelsehiTail。hiT}}while((enext)!null);if(loTail!null){loTail。newTab〔j〕loH}if(hiTail!null){hiTail。newTab〔joldCap〕hiH}}}}}returnnewT}
  1。8的resize和1。7最大不同就是,元素重新求索引位置,不是单纯求hash(length1),而是看元素key的hash值在newCap1的高位是1还是0,如果是1元素索引位置oldCap,如果是0元素索引位置保持不变。get函数(和1。7类似)finalNodeK,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);}}}缩容
  注意当链表长度小于6时,红黑树会变为链表面试考点JDK1。7,hashMap使用头插法为什么会造成死循环?voidtransfer(Entry〔〕newTable,booleanrehash){intnewCapacitynewTable。for(EntryK,Ve:table){while(null!e){第一处EntryK,Vnexte。if(rehash){e。hashnulle。key?0:hash(e。key);}intiindexFor(e。hash,newCapacity);e。nextnewTable〔i〕;newTable〔i〕e;}}}
  原因是多线程并发扩容时,假设A,B两个线程,当A线程执行完第一处,时间片耗尽,线程B按照头插法,完成了完整扩容,此时链表相对于原来是逆序,A线程再继续顺序执行,会造成指针混乱,于是出现死循环。为什么容量是2的指数幂?
  有两点,更好的得到新索引和搭配数组的length1可以使hash(length)hash(length1)作用相等更好的得到新索引,打个比方容量如果一开始时8,后面扩容成16从二进制上看只有最高位不同(length最高位后面都是0),所以在扩容的时候,需要重新用元素的hash值和length1求余实际上只有最高位不同,其他位不变,修改的数据少了,提高了代码的执行效率(1。7这样写,但是没利用到,但是1。8利用了这个特点)image20230201115404578如果扩容不是2的指数幂,那么扩容后的长度低位不会那么均匀,(试想下,如果低位有0的话,是不是每个hash值在这个位置都是0,大大提高了hash冲突的概率,是2的指数幂低位,length1低位全是1)也能更好的降低hash冲突的概率搭配数组的length1可以使hash(length)hash(length1)作用相等如果使用自定义对象作为hashMap的key为什么一定需要重写hashCode和equals方法?
  因为hashMap插入元素,会用到hashCode计算hash值,如果没有重写的话,默认使用Object的实现,即对象的内存地址HashMapKeyk1newHashMapKey(1);HashMapKeyk2newHashMapKey(1);HashMapHashMapKey,StringmapnewHashMap();map。put(k1,test);System。out。println(map。get(k2):map。get(k2));
  上面的例子,如果沒有重写hashCode的话,k1和k2元素肯定不在数组的同一个位置上,因为hashCode使用的是内存地址,所以map。get(k2)null
  那为什么要重写equals呢?
  因为获取元素需要用到equals方法HashMapKeyk1newHashMapKey(1);HashMapKeyk2newHashMapKey(1);HashMapHashMapKey,StringmapnewHashMap();map。put(k1,test);System。out。println(map。get(k2):map。get(k2));
  还是上面的例子,k1和k2,不管有没有重写hashCode都有可能hash值相等(不同元素的hash可能相等),假设k1和k2的hash值相等,当根据key获取元素时,不但会判断元素的hash值还会判断key之间是否equals,如果没有重写equals方法(equals默认对象的内存地址),k1和k2的内存地址肯定不相同,所以map。get(k2)null
  总结:使用自定义对象作为hashMap的key一定需要重写hashCode和equals方法,set集合比较,去重时(先比较hash,hash相同在比较equals),所以一样需要重写。HashMap线程不安全的体现:JDK1。7HashMap线程不安全体现在:死循环、数据丢失JDK1。8HashMap线程不安全体现在:数据覆盖思考问题
  谈谈你理解的HashMap,讲讲其中的getput过程。1。8做了什么优化?是线程安全的嘛?不安全会导致哪些问题?如何解决?有没有线程安全的并发容器?ConcurrentHashMap是如何实现的?1。7、1。8实现有何不同?为什么这么做?引用
  https:crossoverjie。top20180723javaseniorConcurrentHashMapHashMap
  有问题,欢迎私信我哦
投诉 评论 转载

比起塌房不能再塌的李易峰,退出5年的鹿晗才真是让我刮目相看近日,某顶流明星塌方事件在娱乐圈内刮起了万丈波涛,很多粉丝都表示不愿意相信这是真的。毕竟是自己一直喜欢的偶像,实在是接受不了塌房的真相。但无论如何,事情已经发生了,……蒋介石的故里宁波奉化奉化区,隶属于浙江省宁波市,奉化区境内溪口(雪窦山风景区,蒋氏故居)和滕头村生态旅游区是国家级风景名胜区、国家AAAAA级旅游景区。奉化市的溪口镇,这里是一座典型的江南小……国际赛阿根廷VS牙买加南美最强大的球队阿根廷位列世界足球联盟的第3位,而南美则是紧随巴西之后的第二位。29人阵容中,梅西,马丁内斯,迪马利亚都是主力。阿根廷最近7次取得6连胜,4次在净胜球上取得2个……(体育)四战全胜中国队暂列世界大冬会女子冰壶积分榜第一新华社华盛顿1月15日电在当地时间15日于美国普莱西德湖进行的世界大学生冬季运动会女子冰壶循环赛中,中国队以9:2击败澳大利亚队,迄今为止四战全胜,暂列积分榜第一。此前,……过膝裙跑鞋,小脚裤浅口单鞋,初夏40岁女人最不能错过的搭法都说换季先换鞋,其实从春季到夏季,鞋柜里的跑鞋依旧能够派得上用场,随着气温的回升,40岁女人只要再为鞋柜增加一到两双浅口单鞋就可以了。不过很多人或许早就将跑鞋穿腻了,觉得跑鞋除……云南泸沽湖梦幻天堂里的女儿国国庆去哪儿玩这里是最漂亮的一片水,无法想象还有比这更美丽的布景,洛克在美国自己的日记里这样写道,笼罩这里的,是安静和平的奇妙,是上帝创造的最后一块地方,平和、静穆,是一个适合神……830周二四场英超深度情报分享水晶宫,富勒姆,切尔西,利兹联002英超水晶宫vs布伦特福1、水晶宫上赛季排名英超第12位,38轮比赛掌到了48分,落后前十位球队仅有3分。2、水晶宫上赛季丢球仅有46个联赛第7少,甚至比第5名……荣耀Earbuds3Pro发布全球首款支持测温的TWS耳机,出品搜狐科技作者林国振3月17日,荣耀年度音质旗舰真无线耳机荣耀Earbuds3Pro正式发布,这是全球首款采用超大振幅动圈与陶瓷高音单元的同轴双单元的TWS耳机、……你要的hashMap解读来了最近快到金三银四了,不少小伙伴又开始忙忙碌碌找工作了,我也是,秉着为自己也为大家,整理了下hashMap的知识点,希望能对你有所帮助!这里主要是对jdk1。7和jdk1。……小米突然上架新手机128GB5000mAh电池!售价仅999小米一直是主打性价比市场,但是小米品牌在冲击高端之后,价格也随之上涨。1999元的产品也很久没有出现在小米机型上面。不过好在子品牌Redmi很好地继承了中低端价位,千元市场的N……双输!杰伦布朗维金斯互换东家?勇士凯尔特人3换1得不偿失距离总决赛结束已经差不多两个月的时间了,勇士和凯尔特人两支球队在休赛期本来没有什么关联。但是由于维金斯向勇士索要年薪3600万美元的顶薪,而球队需要在他和普尔之间做出选择……赵继伟恩怨分明!王哲林主动前来握手,全程黑脸球迷叫好赵继伟恩怨分明!王哲林主动前来握手,全程黑脸球迷叫好亲情提示:亲爱的读者,如何能每天能读到这样的体育资讯呢?点击右上角的关注按钮即可,您的关注将是我创作的最大……
原神2。4实锤海灯节复刻!前瞻直播宣传图透露了哪些信息?大型粒子对撞机该不该继续日本名将勇夺冠军!曾2连胜国乒大满贯,不久前才打败世界冠军一个人能陪自己走多久,其实从相识就已注定孩子遭遇霸凌时,比还击回去更管用的方法,是教会孩子这些事C罗能否带领葡萄牙夺冠这才是5060岁女人该有的打扮珍珠缎外套八分裤,时髦更高级下载Googleplay商店软件?无需特殊方法行车记录拍得清,推荐盯盯拍Z502023东方卫视待播新剧!肖战李沁井柏然谭松韵黄渤新剧要播了S29赛季闪影花怎么用?新的对抗路尊严,一个传送瞬间改变战局睡觉起来感觉头疼,这是危险在警告你
我的梦幻书房我们为什么那么喜欢讲八卦?力合科技水质监测行业专家,规模优势不够突出难有大作为女足亚洲杯半决赛中国胜日本,短短半年,中国女足为何脱胎换骨?合并计算的方法系统管理员(电脑系统管理员)记忆之门小武iPhonex哪年上市的iPhonex哪一年上市的池塘中的鱼和蟹宝妈应不应该找一份副业?宇宙之问引力常数值是多少?国人对科学应有的了解

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形