如何快速自己实现Map
第一步:定义一个接口publicinterfaceMyMapK,V{向集合中插入值paramkparamvreturnVput(Kk,Vv);根据Key获取集合中的值paramkreturnVget(Kk);获取集合中元素个数returnintsize();清空voidclear();判断是否存在某值paramvaluereturnbooleancontainsValue(Vvalue);判断是否存在某键paramkeyreturnbooleancontainsKey(Kkey);判断是否为空returnbooleanisEmpty();用于获取集合中,键值对的对象paramKparamVinterfaceEntryK,V{获取KeyreturnKgetKey();获取ValuereturnVgetValue();设置ValueparamvaluereturnVsetValue(Vvalue);获取nextreturnEntryK,VgetNext();设置nextparamnextreturnEntryK,VsetNext(EntryK,Vnext);}}
对上述编写的接口以及内容进行说明:Vput(Kk,Vv);Vget(Kk);intsize();voidclear();booleancontainsValue(Vvalue);booleancontainsKey(Kkey);booleanisEmpty();interfaceEntryK,V{}第二步定义一个类实现这个接口
首先定义这个类的成员变量用于存放Entry数据privateEntryK,V〔〕tablenull;记录HashMap的元素个数privateintsize;HashMap集合中数组的默认长度24位移算法privatestaticintdefaultLength14;默认加载因子0。75privatestaticdoubledefaultLoad0。75;
Vput(Kk,Vv)OverridepublicVput(Kk,Vv){if(tablenull){tablenewEntry〔defaultLength〕;}if(sizedefaultLengthdefaultLoad){resize();}intindexgetIndex(k,defaultLength);MyMap。EntryK,Ventrytable〔index〕;while(entry!null){if(entry。getKey()。equals(k)){returnentry。setValue(v);}else{entryentry。getNext();}}table〔index〕newEntry(k,v,table〔index〕);this。size;returnv;}
执行过程:
第一步判断该集合是否需要扩容;
第二步计算位置需要将该元素放置在哪里;
第三步判断是否是修改(可能计算的位置已经有元素存在);
第四步该位置可能已经形成链表(所以需要判断下一个元素)
第五步创建Entry元素并存放在table的index下标上。
intgetIndex(Kk,intlength)privateintgetIndex(Kk,intlength){HashMap是允许null值和nullkeyif(knull){return0;}计算的hashCode码值过大如何处理000001004000001117000000102000000102000000000000000102inthashk。hashCode();returnhash(length1);}
知识点计算下标的方法一般有两种:
(与)算法与得到的值一定不会大于这两个数的最小值〔0,最小值〕
模算法取模后得到的值一定是比取模的数小〔0,取模数)
计算下标:hashCode是根据对象的地址或者字符串的值计算得到的int类型的数值
特点:同一对象多次调用hashCode()方法,必须返回相同的数值〔储存哪个位置在哪个位置获取〕即调用多次如果两个对象根据equals()方法比较是相等的,那么两个对象调用hashCode()方法返回的结果必须相等如果两个对象根据equals()方法比较是不相等的,那么两个对象调用hashCode()方法返回的结果不一定不相等
Vget(Kk)publicVget(Kk){if(table!null){intindexgetIndex(k,defaultLength);MyMap。EntryK,Ventrytable〔index〕;while(entry!null){if(entry。getKey()!nullentry。getKey()。equals(k)){returnentry。getValue();}else{entryentry。getNext();}}}returnnull;}
执行过程:
第一步:根据getIndex(Kk,intlength)查询下标(注意此时获取的下标可能代表好多值)
第二步:根据index获取Entry
第三步:循环判断需要满足两个条件(1。entry不为空2。entry的key等于该值);如果不满足则获取下一个entry继续判断
voidclear()publicvoidclear(){EntryK,V〔〕tab;if((tabtable)!nullsize0){size0;for(inti0;itab。length;i){tab〔i〕null;}}}
booleancontainsValue(Vvalue)publicbooleancontainsValue(Vvalue){EntryK,V〔〕tabtable;if(tab!nullsize0){for(MyMap。EntryK,Ve:tab){for(;e!null;ee。getNext()){Vve。getValue();if(vvalue){returntrue;}elseif(value!nullvalue。equals(v)){returntrue;}}}}returnfalse;}
执行过程:
第一步:将类的成员变量赋值给该方法中的成员变量
第二步:判断该成员变量是否为空,若为空直接返回false
第三步:循环遍历Entry,再次遍历Entry链表中的所有元素
第四步:需要考虑到V可能是对象,所以不能简单的通过来判断。
booleancontainsKey(Kkey)publicbooleancontainsKey(Kkey){1。计算该key对应的hashCodeintindexgetIndex(key,defaultLength);returngetEntry(index,key);}privatebooleangetEntry(inthash,Kkey){EntryK,V〔〕tabtable;if(tab!null){MyMap。EntryK,Ventrytable〔hash〕;while(entry!null){if(entry。getKey()!nullentry。getKey()。equals(key)){returntrue;}else{entryentry。getNext();}if(entrykey){returntrue;}}}returnfalse;}
执行过程:
第一步:根据key计算出对应的hashCodegetIndex(Kk,intlength);
第二步:将类的成员变量赋值给该方法中的成员变量;
第三步:判空,如果为null直接返回false;
第四步:不为空,根据hashCode获取对应的Entry,如果Entry不为空循环判断
第五步:如果entry。getKey()不为空且两者的equals比较相同则返回true;
否则获取entry。getNext(),继续判断;如果都不满足则直接判断entrykey。(考虑到对象的存在)
booleanisEmpty()publicbooleanisEmpty(){EntryK,V〔〕tabtable;return(tabnull)?true:false;}
intsize()publicintsize(){returnthis。size;}
voidresize()
最重要的是扩容方法privatevoidresize(){重新散列if(sizedefaultLengthdefaultLoad){System。out。println(扩容开始);EntryK,V〔〕newTablenewEntry〔defaultLength1〕;MyMap。EntryK,Ventrynull;for(inti0;itable。length;i){entrytable〔i〕;while中的五行代码每一行都是精髓while(entry!null){intindexgetIndex(entry。getKey(),newTable。length);MyMap。EntryK,VoldEntryentry。getNext();entry。setNext(newTable〔index〕);newTable〔index〕(EntryK,V)entry;entryoldEntry;}}tablenewTable;defaultLengthnewTable。length;}}
执行过程:
第一步:判断当前的size是否大于当前的默认的长度默认因子
第二步:如果不大于,则什么都不用做
第三步:如果大于,就需要扩容:
a。定义一个新的table用于临时存储扩容的Entry对象
b。定义一个临时变量entry用于存储每一个下标的Entry对象
c。准备遍历old的table〔0,table。length)
d。取出table〔i〕赋值给b步骤定义的entry(这是一个链表)
e。while循环判断entry是否为空
以下步骤是操作链表(精华):拿到节点重新散列(拿到entry的key,以及临时table的长度)计算新的下标entry并不简单,需要处理key,value以及next得有一个中间变量相当于ab的值互换即ca,ab,bc内部类的实现
具有的成员变量:
Kk;Vvalue
MyMap。EntryK,Vnext;(指针,指向下一个Entry)。
通过setNext()方法实现。staticclassEntryK,VimplementsMyMap。EntryK,V{Kkey;Vvalue;MyMap。EntryK,Vnext;拿到存放的位置后,只需要将keyvalue存放进来首先得先有一个keyvalue创建一个keyvalue对象来存储对象如何去创建我们有一个Entry,通过Entry的构造方法来创建paramkeyparamvalueparamnextpublicEntry(Kkey,Vvalue,MyMap。EntryK,Vnext){this。keykey;this。valuevalue;this。nextnext;}OverridepublicfinalKgetKey(){returnthis。key;}OverridepublicVgetValue(){returnthis。value;}OverridepublicVsetValue(Vvalue){VoldValuethis。value;this。valuevalue;returnoldValue;}OverridepublicfinalStringtoString(){returnkeyvalue;}Overridepublicfinalbooleanequals(Objecto){if(othis){returntrue;}if(oinstanceofMyMap。Entry){MyMap。Entrylt;?,?e(MyMap。Entrylt;?,?)o;if(Objects。equals(key,e。getKey())Objects。equals(value,e。getValue()))returntrue;}returnfalse;}OverridepublicfinalinthashCode(){returnObjects。hashCode(key)Objects。hashCode(value);}OverridepublicMyMap。EntryK,VgetNext(){returnthis。next;}OverridepublicMyMap。EntryK,VsetNext(MyMap。EntryK,Vnext){MyMap。EntryK,VoldNextnext;this。nextnext;returnoldNext;}}
大江大河2定档李光洁搭档王凯开启新里程近日,由上海广播电视台、正午阳光、SMG尚世影业出品,李雪、黄伟执导,王凯、杨烁、董子健、李光洁主演的当代题材电视剧《大江大河2》正式宣布定档,该剧将于12月20日在东方卫视、……
王凯猎狐收官口碑不俗剧情跌宕唱响时代精神主旋律星关系5月8日讯由公安部新闻宣传局、中国国际电视总公司、柠萌影业、柠萌开新和优酷出品的经侦题材电视剧《猎狐》于4月14日开播,该剧由赵冬苓编剧,刘新执导,王凯、王鸥、胡军、刘奕……
热搜神剧大比拼佟大为窦骁鞠婧祎吕佳容星关系5月14日讯最近被微博热搜上一波又一波的神剧成功安利,值得一看的除了有都市剧、青春剧、古装剧各种类型多元的影视好剧外,各位靓丽的主演们也让网友们难以抉择,当然更多人表示:……
双11开门红大屏产品最大赢家,荣耀智慧屏X2系列值得入手荣耀智慧屏自从入市以来,就一直以高标准要求自己,不仅提出了智慧屏五大标准,还坚持开关机无广告原则,其始终以消费者为中心,围绕极致体验来定义品质标准,最终带给消费者行业领先的体验……
都市情感剧爱之初口碑爆棚姜武贡献教科书级演技星关系7月29日讯近日,都市情感大戏《爱之初》正在热播中,这部剧将镜头对准一群30的姐姐和叔叔们,讲述他们不拘泥于世俗眼光,无惧年龄、勇敢追爱的爱情故事。该剧自开播以来,便因为……
电视剧逆光首曝黑白阵容张涵予蓝盈莹实力组合引关注由圣世互娱出品、古天影视、橙子映像、东仑传媒、骑士影业、星谊影业、物源资本、耳东影业联合出品的时尚精英职场剧《逆光》于今日首度曝光黑白分明概念海报及主创阵容,该剧由大满贯影帝张……
抚州宝骏510直降0。1万元,欢迎到店赏车本周宝骏510最新报价:五菱汽车抚州国鼎销售中心店即日起到10月30日限时促销,直降0。1万元,如此优惠的降幅,大家可千万不要错过,店铺地址:抚州市文昌大道与迎宾大道交叉口……
有翡甜虐交织赵丽颖王一博感情升温董璇引爆情怀杀由华策克顿旗下好故事影视出品,吴锦源执导,赵丽颖、王一博领衔主演的古装武侠剧《有翡》已于前日开播,该剧改编自人气作家Priest高分作品《有匪》,以初入江湖的周翡砥砺成长,与豁……
德国SAUTER(首德)钢琴2019感谢有您2020携手共进在过去的2019年中,德国SAUTER(首德)钢琴在您的陪伴下,度过了许许多多珍贵的时刻,也迎来了我们建立200周年庆典。在此辞旧迎新之际,我们诚挚邀请您一起回顾精彩而令人感动……
张嘉倪小大夫收官首部生活情感剧喜获好评近日,由卢伦常导演,王小枪编剧的医疗情感剧《小大夫》完满收官。剧中,张嘉倪饰演了一名年轻漂亮且专业度颇高的副主任医师,。该剧讲述了其与郭靖经历了一番爱恨情仇之后,彼此成就,共同……
从IT圈鄙视链看前端开发有多难?如今鄙视链体现在生活的方方面面,各行各业都有默认一致的鄙视链。IT圈子因为开发语言多样、工程师岗位种类多、技术框架多,也有自己圈子内的鄙视链。按照开发工程师的岗位形成的鄙视链是……
让奔跑成为习惯!毕业刚出来工作的时候,遇到过很多困难,活得很憋屈,在无奈之下,开始了跑步,都说跑步减肥,可几年下来,感觉我也没瘦多少,只是感觉生活状态好了很多!难过的时候跑,开心的时候跑,阴天……