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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

哈希码总结:

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

哈希碼

一 哈希碼

在Java中,哈希碼代表了對象的一種特征,例如我們判斷某兩個字符串是否==,如果其哈希碼相等,則這兩個字符串是相等的。其次,哈希碼是一種數(shù)據(jù)結(jié)構(gòu)的算法。常見的哈希碼的算法有:

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

2:String類的hashCode.根據(jù)String類包含的字符串的內(nèi)容,根據(jù)一種特殊算法返回哈希碼,只要字符串內(nèi)容相同,返回的哈希碼也相同。
3:Integer類,返回的哈希碼就是Integer對象里所包含的那個整數(shù)的數(shù)值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可見,2個一樣大小的Integer對象,返回的哈希碼也一樣。

二 Object對象默認(rèn)的toString()

假如.直接輸出一個實例對象,出現(xiàn)一串字符串,代表什么?

直接輸出一個類的對象的時候,會調(diào)用這個類的toString()方法,這個方法有些類是覆蓋了的,比如String,Integer。你自己寫的類沒有覆蓋這個方法的話就是繼承Object類的這個方法,Object中toString()方法的實輸出格式是這樣的getClass().getName() + “@” + Integer.toHexString(hashCode()) 后面跟的是這個類的哈希碼,如果你希望這個類打印出來輸出你希望的格式,你就要覆蓋這個、toString方法。
測試:

package new_start1;
public class Test1 {
class Person
{
public String name;
public Person(String n)
{
this.name=n;
}
public Person(){}
}
public static void change(Person a)//改變對象a的name值
{
a.name=“haha”;
}
public static void main(String[] args) {
Test1 t=new Test1();
Person p=t.new Person(“zhangsan”); //實例一個對象p
Person a=t.new Person();//又實例一個對象a
System.out.println(“未賦值前,兩者的哈希碼是不相同的:”);
System.out.println(“a.hashCode=”+a.hashCode()+" "+“p.hashCode=”+p.hashCode());
System.out.println(“a.toString()=”+a.toString());
System.out.println(“p.toString()=”+p.toString());
/*
未賦值前,兩者的哈希碼是不相同的:
a.hashCode=366712642 p.hashCode=1829164700
a.toString()=new_start1.Test1Person@15db9742p.toString()=newstart1.Test1Person@15db9742 p.toString()=new_start1.Test1Person@15db9742p.toString()=news?tart1.Test1Person@6d06d69c
/
a=p;
System.out.println(“賦值后,兩者的哈希碼相同:”);
System.out.println(“a.hashCode=”+a.hashCode()+" "+“p.hashCode=”+p.hashCode());
System.out.println(“a.toString()=”+a.toString());
System.out.println(“p.toString()=”+p.toString());
/
賦值后,兩者的哈希碼相同:
a.hashCode=1829164700 p.hashCode=1829164700
a.toString()=new_start1.Test1Person@6d06d69cp.toString()=newstart1.Test1Person@6d06d69c p.toString()=new_start1.Test1Person@6d06d69cp.toString()=news?tart1.Test1Person@6d06d69c
*/
}
}

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

哈希碼具體是什么?

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

常見的哈希碼的算法有:

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

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

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

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

Object中hashCode方法是一個本地方法:public native inthashCode();

對于Java HotSpot VM,首先介紹一個概念就是對象的header,

每個對象都會有一個header,header由兩個機器字表示(8個字節(jié)對于32位架構(gòu),16個字節(jié)對于64位架構(gòu))。

header的第一個字中有7位用做同步及垃圾收集,另外25位存儲對象的hash碼。

header的第二個字存儲指向?qū)?yīng)Class對象的指針(Class對象用來保存類的元數(shù)據(jù)信息及方法表)。

hashcode 作用 :對象實例的唯一標(biāo)識

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

就是兩個不同實例其hashcode在同一運行環(huán)境絕對不一樣 主要用來區(qū)分 兩個實例在物理上是不是同一個對象。

如:

string a =“111”;

string b =“111”;

a和b 的hashcode是一樣的。

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

至于這個

String a = newString(“i love you”);

String b = newString(“i love you”);

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

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

對于Object對象來說,不同的Object對象的hashcode是不同的,它們返回的是對象的地址,equals返回的也是對象的地址。

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

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

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

要從物理上判斷2個對象是否相等,用==就可以了。

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

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

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

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

String a=new String(“foo”);

String b=new String(“foo”);

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

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

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

boolean equals(Object o){

return this==o;

}

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

總結(jié)

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

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