詳談Map的key、value值的數(shù)據(jù)類型不能為基本類型的原因
interface Map<K,V>
Map源碼
/**
* Returns the hash code value for this map entry. The hash code
* of a map entry <tt>e</tt> is defined to be: <pre>
* (e.getKey()==null ? 0 : e.getKey().hashCode()) ^
* (e.getValue()==null ? 0 : e.getValue().hashCode())
* </pre>
* This ensures that <tt>e1.equals(e2)</tt> implies that
* <tt>e1.hashCode()==e2.hashCode()</tt> for any two Entries
* <tt>e1</tt> and <tt>e2</tt>, as required by the general
* contract of <tt>Object.hashCode</tt>.
*
* @return the hash code value for this map entry
* @see Object#hashCode()
* @see Object#equals(Object)
* @see #equals(Object)
*/
int hashCode();
hashCode返回 (e.getKey()==null ? 0 : e.getKey().hashCode()) ^(e.getValue()==null ? 0 : e.getValue().hashCode())
class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
HashMap源碼中:
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
補(bǔ)充知識(shí):java hashmap key long 和int 區(qū)別
最近同事問起,map里面存的key 是int 類型的,存了一個(gè) Integera =123,為什么使用long 123 作為key get,取出來的是空,這個(gè)問題粗想了一下,感覺long和int 本身 類型不同,肯定不能是同一個(gè)key,后來細(xì)研究了一下,跟了一下源碼,發(fā)現(xiàn)邏輯不是那么簡(jiǎn)單。
簡(jiǎn)單測(cè)試了一下,如下代碼
Map<Object,String> map = new HashMap<>(); Integer b = 123; Long c =123L; map.put(b, b+"int"); System.out.println(b.hashCode() == c.hashCode()); //true System.out.println(map.get(c)); //null map.put(c, c+"long"); // size =2
簡(jiǎn)單的總結(jié)了一下問題:
1、HashMap 是把key做hash 然后作為數(shù)組下標(biāo),但是 b 和c 的hashcode 竟然是相同的,為什么 get(c) 為空
2、HashMap 存入c 發(fā)現(xiàn) size=2 ,hashcode相同 為什么 size=2,get(c) =123long
帶著上面兩個(gè)問題跟了一遍源碼,問題豁然開朗
1、hashmap在存入的時(shí)候,先對(duì)key 做一遍 hash,以hash值作為數(shù)組下標(biāo),如果發(fā)現(xiàn) 下標(biāo)已有值,判斷 存的key 跟傳入的key是不是相同,使用 (k = p.key) == key || (key != null && key.equals(k)) ,如果相同覆蓋,而Interger的equals 方法如下:
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
Integer 和 Long 肯定不是一個(gè)類型,返回 false,這時(shí)候 hashmap 以 hashkey 沖突來處理,存入鏈表,所以 Long 123 和 Integer 123 hashmap會(huì)認(rèn)為是 hash沖突
2、hashmap 在 get的時(shí)候,也是先做 hash處理,根據(jù)hash值查找對(duì)應(yīng)的數(shù)組下標(biāo),如果找到,使用存入時(shí)候的判斷條件
(k = first.key) == key || (key != null && key.equals(k)) 如果相等就返回,不相等,查找當(dāng)前值的next有沒有值,有繼續(xù)根據(jù)邏輯判斷,所以 存入Integer 123 根據(jù) Long 123 來獲取返回的 是 NULL
至此,解析完畢。
以上這篇詳談Map的key、value值的數(shù)據(jù)類型不能為基本類型的原因就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何使用BeanUtils.copyProperties進(jìn)行對(duì)象之間的屬性賦值
這篇文章主要介紹了使用BeanUtils.copyProperties進(jìn)行對(duì)象之間的屬性賦值,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
java實(shí)現(xiàn)角色及菜單權(quán)限的項(xiàng)目實(shí)踐
在Java中,實(shí)現(xiàn)角色及菜單權(quán)限管理涉及定義實(shí)體類、設(shè)計(jì)數(shù)據(jù)庫(kù)表、實(shí)現(xiàn)服務(wù)層和控制器層,這種管理方式有助于有效控制用戶權(quán)限,適用于企業(yè)級(jí)應(yīng)用,感興趣的可以一起來了解一下2024-09-09
JAVA通過HttpURLConnection 上傳和下載文件的方法
這篇文章主要介紹了JAVA通過HttpURLConnection 上傳和下載文件的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09
一個(gè)簡(jiǎn)易的Java多頁(yè)面隊(duì)列爬蟲程序
這篇文章主要為大家詳細(xì)介紹了一個(gè)多頁(yè)面的java爬蟲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08
intelliJ idea 2023 配置Tomcat 8圖文教程
這篇文章主要介紹了intelliJ idea 2023 配置Tomcat 8教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
Spring Cloud Hystrix入門和Hystrix命令原理分析
這篇文章主要介紹了Spring Cloud Hystrix入門和Hystrix命令原理分析,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
Java實(shí)現(xiàn)輸出數(shù)字三角形實(shí)例代碼
大家好,本篇文章主要講的是Java實(shí)現(xiàn)輸出三角形實(shí)例代碼,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2022-01-01
Tomcat集群和Session復(fù)制應(yīng)用介紹
本文將詳細(xì)介紹Tomcat集群和Session復(fù)制應(yīng)用,需要了解的朋友可以參考下2012-11-11
mybatis取別名typeAliases標(biāo)簽的位置放錯(cuò)導(dǎo)致報(bào)錯(cuò)的解決
這篇文章主要介紹了mybatis取別名typeAliases標(biāo)簽的位置放錯(cuò)導(dǎo)致報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09

