详谈Map的key、value值的数据类型不能为基本类型的原因
interfaceMap
Map源码
/** *Returnsthehashcodevalueforthismapentry.Thehashcode *ofamapentryeisdefinedtobe:*(e.getKey()==null?0:e.getKey().hashCode())^ *(e.getValue()==null?0:e.getValue().hashCode()) **Thisensuresthate1.equals(e2)impliesthat *e1.hashCode()==e2.hashCode()foranytwoEntries *e1ande2,asrequiredbythegeneral *contractofObject.hashCode. * *@returnthehashcodevalueforthismapentry *@seeObject#hashCode() *@seeObject#equals(Object) *@see#equals(Object) */ inthashCode();
hashCode返回(e.getKey()==null?0:e.getKey().hashCode())^(e.getValue()==null?0:e.getValue().hashCode())
classHashMap
extendsAbstractMap implementsMap ,Cloneable,Serializable
HashMap源码中:
publicfinalinthashCode(){ returnObjects.hashCode(key)^Objects.hashCode(value); }
staticfinalinthash(Objectkey){ inth; return(key==null)?0:(h=key.hashCode())^(h>>>16); }
publicfinalbooleanequals(Objecto){ if(o==this) returntrue; if(oinstanceofMap.Entry){ Map.Entry,?>e=(Map.Entry,?>)o; if(Objects.equals(key,e.getKey())&& Objects.equals(value,e.getValue())) returntrue; } returnfalse; }
补充知识:javahashmapkeylong和int区别
最近同事问起,map里面存的key是int类型的,存了一个Integera=123,为什么使用long123作为keyget,取出来的是空,这个问题粗想了一下,感觉long和int本身类型不同,肯定不能是同一个key,后来细研究了一下,跟了一下源码,发现逻辑不是那么简单。
简单测试了一下,如下代码
Map
简单的总结了一下问题:
1、HashMap是把key做hash然后作为数组下标,但是b和c的hashcode竟然是相同的,为什么get(c)为空
2、HashMap存入c发现size=2,hashcode相同为什么size=2,get(c)=123long
带着上面两个问题跟了一遍源码,问题豁然开朗
1、hashmap在存入的时候,先对key做一遍hash,以hash值作为数组下标,如果发现下标已有值,判断存的key跟传入的key是不是相同,使用(k=p.key)==key||(key!=null&&key.equals(k)),如果相同覆盖,而Interger的equals方法如下:
if(objinstanceofInteger){ returnvalue==((Integer)obj).intValue(); } returnfalse;
Integer和Long肯定不是一个类型,返回false,这时候hashmap以hashkey冲突来处理,存入链表,所以Long123和Integer123hashmap会认为是hash冲突
2、hashmap在get的时候,也是先做hash处理,根据hash值查找对应的数组下标,如果找到,使用存入时候的判断条件
(k=first.key)==key||(key!=null&&key.equals(k))如果相等就返回,不相等,查找当前值的next有没有值,有继续根据逻辑判断,所以存入Integer123根据Long123来获取返回的是NULL
至此,解析完毕。
以上这篇详谈Map的key、value值的数据类型不能为基本类型的原因就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。