日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

哈希码 总结

發(fā)布時(shí)間:2024/1/1 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哈希码 总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

哈希碼


哈希碼是一種數(shù)據(jù)結(jié)構(gòu)的算法。


哈希碼具體是什么?

答:hashCode是jdk根據(jù)對(duì)象的地址或者字符串或者數(shù)字算出來(lái)的int類型的數(shù)值

?

常見(jiàn)的哈希碼的算法有:

?

1:Object類的hashCode.返回對(duì)象的內(nèi)存地址經(jīng)過(guò)處理后的結(jié)構(gòu),由于每個(gè)對(duì)象的內(nèi)存地址都不一樣,所以哈希碼也不一樣。

?

2:String類的hashCode.根據(jù)String類包含的字符串的內(nèi)容,根據(jù)一種特殊算法返回哈希碼,只要字符串內(nèi)容相同,返回的哈希碼也相同

?

3:Integer類,返回的哈希碼就是Integer對(duì)象里所包含的那個(gè)整數(shù)的數(shù)值,例如Integer i1=new Integer(100),i1.hashCode的值就是100

?

?

?

?

?

跟蹤Object類的native方法hashCode方法從jvm源碼中得到了下面的一些內(nèi)容,供參考。

?

ObjecthashCode方法是一個(gè)本地方法:public native inthashCode();

?

對(duì)于Java HotSpot VM,首先介紹一個(gè)概念就是對(duì)象的header,

?

每個(gè)對(duì)象都會(huì)有一個(gè)headerheader由兩個(gè)機(jī)器字表示(8個(gè)字節(jié)對(duì)于32位架構(gòu),16個(gè)字節(jié)對(duì)于64位架構(gòu))

??

header的第一個(gè)字中有7位用做同步及垃圾收集,另外25位存儲(chǔ)對(duì)象的hash碼。

?

header的第二個(gè)字存儲(chǔ)指向?qū)?yīng)Class對(duì)象的指針(Class對(duì)象用來(lái)保存類的元數(shù)據(jù)信息及方法表)

?

?

?

?

hashcode 作用?:對(duì)象實(shí)例的唯一標(biāo)識(shí)

?

在同一運(yùn)行環(huán)境下 hashcode 的值是唯一的

就是兩個(gè)不同實(shí)例其hashcode在同一運(yùn)行環(huán)境絕對(duì)不一樣 主要用來(lái)區(qū)分 兩個(gè)實(shí)例在物理上是不是同一個(gè)對(duì)象。

如:?

string a ="111";

string b ="111";

a和b hashcode是一樣的。

其原因是java的字符串池優(yōu)化原因,你聲明一個(gè)字符串時(shí)JVM會(huì)先去查找 字符串池 是否有相同字符串有將已經(jīng)有的字符串對(duì)象的引用返回?而不是新生成一個(gè)字符對(duì)象到內(nèi)存沒(méi)有 新生成 并將其引用放入字符串池 如此循環(huán)所以他們是同一個(gè)對(duì)象 hashcode也一樣

至于這個(gè)

String a = newString("i love you");

String b = newString("i love you");

如果hashcode也一樣的話 那他們應(yīng)該也是類似的優(yōu)化。jdk5 好像不一樣吧?

?

?

?

hashcode()是要在容器里面的MAP這個(gè)才能體現(xiàn)其價(jià)值,在MAP里面要是重寫(xiě)equals,就要重寫(xiě)hashcode的方法,只要equals為真,那么hashcode也應(yīng)該一樣。平時(shí)其他的使用hashcode沒(méi)什么大用。

?

?

對(duì)于Object對(duì)象來(lái)說(shuō),不同的Object對(duì)象的hashcode是不同的,它們返回的是對(duì)象的地址,equals返回的也是對(duì)象的地址。

?

所以在自己定義的類中如果要添加到集合對(duì)象中,最好是要重寫(xiě)hashcode和equals方法,不然會(huì)自動(dòng)繼承自O(shè)bject類中的兩個(gè)方法根據(jù)對(duì)象地址來(lái)判斷。在重寫(xiě)自己定義的類時(shí),通常是在類中的根據(jù)某個(gè)值如name.hashcode();來(lái)進(jìn)行判斷。

?

?


一般來(lái)講,equals這個(gè)方法是給用戶調(diào)用的,如果你想判斷2個(gè)對(duì)象是否相等,你可以重寫(xiě)equals方法,然后在代碼中調(diào)用,就可以判斷他們是否相等了。簡(jiǎn)單來(lái)講,equals方法主要是用來(lái)判斷從表面上看或者從內(nèi)容上看,2個(gè)對(duì)象是不是相等。舉個(gè)例子,有個(gè)學(xué)生類,屬性只有姓名和性別,那么我們可以認(rèn)為只要姓名和性別相等,那么就說(shuō)這2個(gè)對(duì)象是相等的。

hashcode方法一般用戶不會(huì)去調(diào)用,比如在hashmap中,由于key是不可以重復(fù)的,他在判斷key是不是重復(fù)的時(shí)候就判斷了hashcode這個(gè)方法,而且也用到了equals方法。這里不可以重復(fù)是說(shuō)equals和hashcode只要有一個(gè)不等就可以了!所以簡(jiǎn)單來(lái)講,hashcode相當(dāng)于是一個(gè)對(duì)象的編碼,就好像文件中的md5,他和equals不同就在于他返回的是int型的,比較起來(lái)不直觀。我們一般在覆蓋equals的同時(shí)也要覆蓋hashcode,讓他們的邏輯一致。舉個(gè)例子,還是剛剛的例子,如果姓名和性別相等就算2個(gè)對(duì)象相等的話,那么hashcode的方法也要返回姓名的hashcode值加上性別的hashcode值,這樣從邏輯上,他們就一致了。

要從物理上判斷2個(gè)對(duì)象是否相等,用==就可以了。


"=="和equals方法究竟有什么區(qū)別?


==操作符專門(mén)用來(lái)比較兩個(gè)變量的值是否相等,也就是用于比較變量所對(duì)應(yīng)的內(nèi)存中所存儲(chǔ)的數(shù)值是否相同,要比較兩個(gè)基本類型的數(shù)據(jù)或兩個(gè)引用變量是否相等,只能用==操作符

如果一個(gè)變量指向的數(shù)據(jù)是對(duì)象類型的,那么,這時(shí)候涉及了兩塊內(nèi)存,對(duì)象本身占用一塊內(nèi)存(堆內(nèi)存),變量也占用一塊內(nèi)存,例如Objet obj = new Object();變量obj是一個(gè)內(nèi)存,new Object()是另一個(gè)內(nèi)存,此時(shí),變量obj所對(duì)應(yīng)的內(nèi)存中存儲(chǔ)的數(shù)值就是對(duì)象占用的那塊內(nèi)存的首地址。對(duì)于指向?qū)ο箢愋偷淖兞?#xff0c;如果要比較兩個(gè)變量是否指向同一個(gè)對(duì)象,即要看這兩個(gè)變量所對(duì)應(yīng)的內(nèi)存中的數(shù)值是否相等,這時(shí)候就需要用==操作符進(jìn)行比較。

equals方法是用于比較兩個(gè)獨(dú)立對(duì)象的內(nèi)容是否相同,就好比去比較兩個(gè)人的長(zhǎng)相是否相同,它比較的兩個(gè)對(duì)象是獨(dú)立的。例如,對(duì)于下面的代碼:

String?a=new?String("foo");

String?b=new?String("foo");

兩條new語(yǔ)句創(chuàng)建了兩個(gè)對(duì)象,然后用a,b這兩個(gè)變量分別指向了其中一個(gè)對(duì)象,這是兩個(gè)不同的對(duì)象,它們的首地址是不同的,即a和b中存儲(chǔ)的數(shù)值是不相同的,所以,表達(dá)式a==b將返回false,而這兩個(gè)對(duì)象中的內(nèi)容是相同的,所以,表達(dá)式a.equals(b)將返回true。

在實(shí)際開(kāi)發(fā)中,我們經(jīng)常要比較傳遞進(jìn)行來(lái)的字符串內(nèi)容是否等,例如,String input = …;input.equals(“quit”),許多人稍不注意就使用==進(jìn)行比較了,這是錯(cuò)誤的,隨便從網(wǎng)上找?guī)讉€(gè)項(xiàng)目實(shí)戰(zhàn)的教學(xué)視頻看看,里面就有大量這樣的錯(cuò)誤。記住,字符串的比較基本上都是使用equals方法。

如果一個(gè)類沒(méi)有自己定義equals方法,那么它將繼承Object類的equals方法,Object類的equals方法的實(shí)現(xiàn)代碼如下:

boolean?equals(Object?o){

return?this==o;

}

這說(shuō)明,如果一個(gè)類沒(méi)有自己定義equals方法,它默認(rèn)的equals方法(從Object類繼承的)就是使用==操作符,也是在比較兩個(gè)變量指向的對(duì)象是否是同一對(duì)象,這時(shí)候使用equals和使用==會(huì)得到同樣的結(jié)果,如果比較的是兩個(gè)獨(dú)立的對(duì)象則總返回false。如果你編寫(xiě)的類希望能夠比較該類創(chuàng)建的兩個(gè)實(shí)例對(duì)象的內(nèi)容是否相同,那么你必須覆蓋equals方法,由你自己寫(xiě)代碼來(lái)決定在什么情況即可認(rèn)為兩個(gè)對(duì)象的內(nèi)容是相同的。



?

?


總結(jié)

以上是生活随笔為你收集整理的哈希码 总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。