hashcode、equals
一、hashcode是什么?
1、hash和hash表是什么?
想要知道這個(gè)hashcode,首先得知道hash,通過(guò)百度百科看一下
hash是一個(gè)函數(shù),該函數(shù)中的實(shí)現(xiàn)就是一種算法,就是通過(guò)一系列的算法來(lái)得到一個(gè)hash值,這個(gè)時(shí)候,我們就需要知道另一個(gè)東西,hash表,通過(guò)hash算法得到的hash值就在這張hash表中,也就是說(shuō),hash表就是所有的hash值組成的,有很多種hash函數(shù),也就代表著有很多種算法得到hash值,如上面截圖的三種,等會(huì)我們就拿第一種來(lái)說(shuō)。
2、hashcode
有了前面的基礎(chǔ),這里講解就簡(jiǎn)單了,hashcode就是通過(guò)hash函數(shù)得來(lái)的,通俗的說(shuō),就是通過(guò)某一種算法得到的,hashcode就是在hash表中有對(duì)應(yīng)的位置。
每個(gè)對(duì)象都有hashcode,對(duì)象的hashcode怎么得來(lái)的呢?
首先一個(gè)對(duì)象肯定有物理地址,在別的博文中會(huì)hashcode說(shuō)成是代表對(duì)象的地址,這里肯定會(huì)讓讀者形成誤區(qū),對(duì)象的物理地址跟這個(gè)hashcode地址不一樣,hashcode代表對(duì)象的地址說(shuō)的是對(duì)象在hash表中的位置,物理地址說(shuō)的對(duì)象存放在內(nèi)存中的地址,那么對(duì)象如何得到hashcode呢?通過(guò)對(duì)象的內(nèi)部地址(也就是物理地址)轉(zhuǎn)換成一個(gè)整數(shù),然后該整數(shù)通過(guò)hash函數(shù)的算法就得到了hashcode,所以,hashcode是什么呢?就是在hash表中對(duì)應(yīng)的位置。這里如果還不是很清楚的話,舉個(gè)例子,hash表中有 hashcode為1、hashcode為2、(…)3、4、5、6、7、8這樣八個(gè)位置,有一個(gè)對(duì)象A,A的物理地址轉(zhuǎn)換為一個(gè)整數(shù)17(這是假如),就通過(guò)直接取余算法,17%8=1,那么A的hashcode就為1,且A就在hash表中1的位置。肯定會(huì)有其他疑問(wèn),接著看下面,這里只是舉個(gè)例子來(lái)讓你們知道什么是hashcode的意義。
二、hashcode有什么作用呢?
前面說(shuō)了這么多關(guān)于hash函數(shù),和hashcode是怎么得來(lái)的,還有hashcode對(duì)應(yīng)的是hash表中的位置,可能大家就有疑問(wèn),為什么hashcode不直接寫(xiě)物理地址呢,還要另外用一張hash表來(lái)代表對(duì)象的地址?接下來(lái)就告訴你hashcode的作用,
1、HashCode的存在主要是為了查找的快捷性,HashCode是用來(lái)在散列存儲(chǔ)結(jié)構(gòu)中確定對(duì)象的存儲(chǔ)地址的(后半句說(shuō)的用hashcode來(lái)代表對(duì)象就是在hash表中的位置)
為什么hashcode就查找的更快,比如:我們有一個(gè)能存放1000個(gè)數(shù)這樣大的內(nèi)存中,在其中要存放1000個(gè)不一樣的數(shù)字,用最笨的方法,就是存一個(gè)數(shù)字,就遍歷一遍,看有沒(méi)有相同得數(shù),當(dāng)存了900個(gè)數(shù)字,開(kāi)始存901個(gè)數(shù)字的時(shí)候,就需要跟900個(gè)數(shù)字進(jìn)行對(duì)比,這樣就很麻煩,很是消耗時(shí)間,用hashcode來(lái)記錄對(duì)象的位置,來(lái)看一下。hash表中有1、2、3、4、5、6、7、8個(gè)位置,存第一個(gè)數(shù),hashcode為1,該數(shù)就放在hash表中1的位置,存到100個(gè)數(shù)字,hash表中8個(gè)位置會(huì)有很多數(shù)字了,1中可能有20個(gè)數(shù)字,存101個(gè)數(shù)字時(shí),他先查hashcode值對(duì)應(yīng)的位置,假設(shè)為1,那么就有20個(gè)數(shù)字和他的hashcode相同,他只需要跟這20個(gè)數(shù)字相比較(equals),如果每一個(gè)相同,那么就放在1這個(gè)位置,這樣比較的次數(shù)就少了很多,實(shí)際上hash表中有很多位置,這里只是舉例只有8個(gè),所以比較的次數(shù)會(huì)讓你覺(jué)得也挺多的,實(shí)際上,如果hash表很大,那么比較的次數(shù)就很少很少了。 通過(guò)對(duì)原始方法和使用hashcode方法進(jìn)行對(duì)比,我們就知道了hashcode的作用,并且為什么要使用hashcode了
三、equals方法和hashcode的關(guān)系?
通過(guò)前面這個(gè)例子,大概可以知道,先通過(guò)hashcode來(lái)比較,如果hashcode相等,那么就用equals方法來(lái)比較兩個(gè)對(duì)象是否相等,用個(gè)例子說(shuō)明:上面說(shuō)的hash表中的8個(gè)位置,就好比8個(gè)桶,每個(gè)桶里能裝很多的對(duì)象,對(duì)象A通過(guò)hash函數(shù)算法得到將它放到1號(hào)桶中,當(dāng)然肯定有別的對(duì)象也會(huì)放到1號(hào)桶中,如果對(duì)象B也通過(guò)算法分到了1號(hào)桶,那么它如何識(shí)別桶中其他對(duì)象是否和它一樣呢,這時(shí)候就需要equals方法來(lái)進(jìn)行篩選了。
1、如果兩個(gè)對(duì)象equals相等,那么這兩個(gè)對(duì)象的HashCode一定也相同
2、如果兩個(gè)對(duì)象的HashCode相同,不代表兩個(gè)對(duì)象就相同,只能說(shuō)明這兩個(gè)對(duì)象在散列存儲(chǔ)結(jié)構(gòu)中,存放于同一個(gè)位置
這兩條你們就能夠理解了。
四、為什么equals方法重寫(xiě)的話,建議也一起重寫(xiě)hashcode方法?
(如果對(duì)象的equals方法被重寫(xiě),那么對(duì)象的HashCode方法也盡量重寫(xiě))
舉個(gè)例子,其實(shí)就明白了這個(gè)道理,
比如:有個(gè)A類重寫(xiě)了equals方法,但是沒(méi)有重寫(xiě)hashCode方法,看輸出結(jié)果,對(duì)象a1和對(duì)象a2使用equals方法相等,按照上面的hashcode的用法,那么他們兩個(gè)的hashcode肯定相等,但是這里由于沒(méi)重寫(xiě)hashcode方法,他們兩個(gè)hashcode并不一樣,所以,我們?cè)谥貙?xiě)了equals方法后,盡量也重寫(xiě)了hashcode方法,通過(guò)一定的算法,使他們?cè)趀quals相等時(shí),也會(huì)有相同的hashcode值。
實(shí)例:現(xiàn)在來(lái)看一下String的源碼中的equals方法和hashcode方法。這個(gè)類就重寫(xiě)了這兩個(gè)方法,現(xiàn)在為什么需要重寫(xiě)這兩個(gè)方法了吧?
equals方法:其實(shí)跟我上面寫(xiě)的那個(gè)例子是一樣的原理,所以通過(guò)源碼又知道了String的equals方法驗(yàn)證的是兩個(gè)字符串的值是否一樣。還有Double類也重寫(xiě)了這些方法。很多類有比較這類的,都重寫(xiě)了這兩個(gè)方法,因?yàn)樵谒蓄惖母割怬bject中。equals的功能就是 ==號(hào)的功能。你們還可以比較String對(duì)象的equals和==的區(qū)別啦。這里不再說(shuō)明。
hashcode方法
總結(jié)
以上是生活随笔為你收集整理的hashcode、equals的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。