HashMap

  • HashMap實(shí)際上是一個(gè)“鏈表散列”的數(shù)據(jù)結(jié)構(gòu),即數(shù)組和鏈表的結(jié)合體。HashMap 底層就是一個(gè)數(shù)組結(jié)構(gòu),數(shù)組中的每一項(xiàng)又是一個(gè)鏈表。當(dāng)新建一個(gè) HashMap 的時(shí)候,就會(huì)初始化一個(gè)數(shù)組。


    image.png

hashCode常規(guī)協(xié)定:

  • 在Java應(yīng)用程序執(zhí)行期間,在同一個(gè)對(duì)象上多次調(diào)用hashCode()方法時(shí),必須一致的返回相同的整數(shù),前提是對(duì)象上 equals 比較中所用的信息沒(méi)有被修改。從某一應(yīng)用程序的一次執(zhí)行到同一應(yīng)用程序的另一次執(zhí)行,該整數(shù)無(wú)需保持一致。
    如果根據(jù) equals(Object) 方法,兩個(gè)對(duì)象是相等的,那么在兩個(gè)對(duì)象中的每個(gè)對(duì)象上調(diào)用 hashCode 方法都必須生成相同的整數(shù)結(jié)果。
  • 以下情況不 是必需的:如果根據(jù) equals(java.lang.Object) 方法,兩個(gè)對(duì)象不相等,那么在兩個(gè)對(duì)象中的任一對(duì)象上調(diào)用 hashCode 方法必定會(huì)生成不同的整數(shù)結(jié)果。但是,程序員應(yīng)該知道,為不相等的對(duì)象生成不同整數(shù)結(jié)果可以提高哈希表的性能。
  • 當(dāng)equals方法被重寫(xiě)時(shí),通常有必要重寫(xiě) hashCode 方法,以維護(hù) hashCode 方法的常規(guī)協(xié)定,該協(xié)定聲明相等對(duì)象必須具有相等的哈希碼。
  • hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用來(lái)在散列存儲(chǔ)結(jié)構(gòu)中確定對(duì)象的存儲(chǔ)地址的;
  • 如果兩個(gè)對(duì)象相同,就是適用于equals(java.lang.Object) 方法,那么這兩個(gè)對(duì)象的hashCode一定要相同;
  • 兩個(gè)對(duì)象的hashCode相同,并不一定表示兩個(gè)對(duì)象就相同,也就是不一定適用于equals(java.lang.Object) 方法,只能夠說(shuō)明這兩個(gè)對(duì)象在散列存儲(chǔ)結(jié)構(gòu)中,如Hashtable,他們“存放在同一個(gè)籃子里”。

對(duì)最后一條的說(shuō)明:
hashCode是用來(lái)查找的:
比如內(nèi)存中有這樣的位置 :0 1 2 3 4 5 6 7
而我有個(gè)類(lèi),這個(gè)類(lèi)有個(gè)字段叫ID,我要把這個(gè)類(lèi)存放在以上8個(gè)位置之一,如果不用hashcode而任意存放,那么當(dāng)查找時(shí)就需要到這八個(gè)位置里挨個(gè)去找,或者用二分法一類(lèi)的算法。
而使用hashCode那就會(huì)使效率提高很多。

我們這個(gè)類(lèi)中有個(gè)字段叫ID,那么我們就定義我們的hashcode為ID%8,然后把我們的類(lèi)存放在取得得余數(shù)那個(gè)位置。比如我們的ID為9,9除8的余數(shù)為1,那么我們就把該類(lèi)存在1這個(gè)位置,如果ID是13,求得的余數(shù)是5,那么我們就把該類(lèi)放在5這個(gè)位置。這樣,以后在查找該類(lèi)時(shí)就可以通過(guò)ID除 8求余數(shù)直接找到存放的位置了。
但是如果兩個(gè)類(lèi)有相同的hashcode怎么辦那(我們假設(shè)上面的類(lèi)的ID不是唯一的),例如9除以8和17除以8的余數(shù)都是1,那么這是不是合法的,回答是:可以這樣。那么如何判斷呢?在這個(gè)時(shí)候就需要定義 equals了。
也就是說(shuō),我們先通過(guò) hashcode來(lái)判斷兩個(gè)類(lèi)是否存放某個(gè)桶里,但這個(gè)桶里可能有很多類(lèi),那么我們就需要再通過(guò) equals 來(lái)在這個(gè)桶里找到我們要的類(lèi)。
那么。重寫(xiě)了equals(),為什么還要重寫(xiě)hashCode()呢?
想想,你要在一個(gè)桶里找東西,你必須先要找到這個(gè)桶啊,你不通過(guò)重寫(xiě)hashcode()來(lái)找到桶,光重寫(xiě)equals()有什么用啊


總結(jié):

就像一開(kāi)始那張圖片顯示的那樣,hashMap中的hashCode用來(lái)確認(rèn)要搜索的文件在數(shù)組中的位置,但是由于可能存在兩個(gè)類(lèi)可能存在同一個(gè)hashCode的情況,就是說(shuō),一個(gè)數(shù)組的特定一個(gè)位置有可能存在多個(gè)數(shù)據(jù),這在HasnMap中就表現(xiàn)為上圖中的那個(gè)鏈表,這個(gè)鏈表中存儲(chǔ)的對(duì)象擁有同樣的hashCode,所以查找的時(shí)候需要找到對(duì)象在數(shù)組中的位置,還需要和鏈表中的位置進(jìn)行對(duì)比。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • HashMap 是 Java 面試必考的知識(shí)點(diǎn),面試官?gòu)倪@個(gè)小知識(shí)點(diǎn)就可以了解我們對(duì) Java 基礎(chǔ)的掌握程度。網(wǎng)...
    野狗子嗷嗷嗷閱讀 6,812評(píng)論 9 107
  • Java集合:HashMap源碼剖析 一、HashMap概述 二、HashMap的數(shù)據(jù)結(jié)構(gòu) 三、HashMap源碼...
    記住時(shí)光閱讀 781評(píng)論 2 1
  • HashMap HashMap概述 HashMap基于哈希表的 Map 接口的實(shí)現(xiàn)。此實(shí)現(xiàn)提供所有可選的映射操作,...
    史路比閱讀 326評(píng)論 0 6
  • 2013年6月相愛(ài),2014年9月開(kāi)始異國(guó)戀,2015年9月Selina回國(guó),2016年3月分手。但,這個(gè)分手卻藕...
    陳煒杭閱讀 266評(píng)論 0 0
  • 日內(nèi)焦點(diǎn): 15:30 瑞士3M LIBOR目標(biāo)利率 15:30 瑞士伯爾尼 瑞士央行貨幣政策評(píng)估 19:00 英...
    mengpo閱讀 510評(píng)論 0 0

友情鏈接更多精彩內(nèi)容