国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Java > 正文

詳解Java中用于查找對(duì)象哈希碼值的hashCode()函數(shù)

2019-11-26 14:17:02
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

理解
hashCode() 的作用是獲取哈希碼,也稱為散列碼;它實(shí)際上是返回一個(gè)int整數(shù)。這個(gè)哈希碼的作用是確定該對(duì)象在哈希表中的索引位置。
hashCode() 定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode() 函數(shù)。
雖然,每個(gè)Java類都包含hashCode() 函數(shù)。但是,僅僅當(dāng)創(chuàng)建并某個(gè)“類的散列表”(關(guān)于“散列表”見(jiàn)下面說(shuō)明)時(shí),該類的hashCode() 才有用(作用是:確定該類的每一個(gè)對(duì)象在散列表中的位置;其它情況下(例如,創(chuàng)建類的單個(gè)對(duì)象,或者創(chuàng)建類的對(duì)象數(shù)組等等),類的hashCode() 沒(méi)有作用。
上面的散列表,指的是:Java集合中本質(zhì)是散列表的類,如HashMap,Hashtable,HashSet。
也就是說(shuō):hashCode() 在散列表中才有用,在其它情況下沒(méi)用。在散列表中hashCode() 的作用是獲取對(duì)象的散列碼,進(jìn)而確定該對(duì)象在散列表中的位置。
我們都知道,散列表存儲(chǔ)的是鍵值對(duì)(key-value),它的特點(diǎn)是:能根據(jù)“鍵”快速的檢索出對(duì)應(yīng)的“值”。這其中就利用到了散列碼!
散列表的本質(zhì)是通過(guò)數(shù)組實(shí)現(xiàn)的。當(dāng)我們要獲取散列表中的某個(gè)“值”時(shí),實(shí)際上是要獲取數(shù)組中的某個(gè)位置的元素。而數(shù)組的位置,就是通過(guò)“鍵”來(lái)獲取的;更進(jìn)一步說(shuō),數(shù)組的位置,是通過(guò)“鍵”對(duì)應(yīng)的散列碼計(jì)算得到的。
下面,我們以HashSet為例,來(lái)深入說(shuō)明hashCode()的作用。
假設(shè),HashSet中已經(jīng)有1000個(gè)元素。當(dāng)插入第1001個(gè)元素時(shí),需要怎么處理?因?yàn)镠ashSet是Set集合,它允許有重復(fù)元素。
“將第1001個(gè)元素逐個(gè)的和前面1000個(gè)元素進(jìn)行比較”?顯然,這個(gè)效率是相等低下的。散列表很好的解決了這個(gè)問(wèn)題,它根據(jù)元素的散列碼計(jì)算出元素在散列表中的位置,然后將元素插入該位置即可。對(duì)于相同的元素,自然是只保存了一個(gè)。
由此可知,若兩個(gè)元素相等,它們的散列碼一定相等;但反過(guò)來(lái)確不一定。在散列表中,
1、如果兩個(gè)對(duì)象相等,那么它們的hashCode()值一定要相同;
2、如果兩個(gè)對(duì)象hashCode()相等,它們并不一定相等。
注意:這是在散列表中的情況。在非散列表中一定如此!

示例
我們來(lái)看一個(gè)具體的示例吧,

public class HashTest {   private int i;    public int getI() {     return i;   }    public void setI(int i) {     this.i = i;   }    public int hashCode() {     return i % 10;   }    public final static void main(String[] args) {     HashTest a = new HashTest();     HashTest b = new HashTest();     a.setI(1);     b.setI(1);     Set<HashTest> set = new HashSet<HashTest>();     set.add(a);     set.add(b);     System.out.println(a.hashCode() == b.hashCode());     System.out.println(a.equals(b));     System.out.println(set);   } } 

這個(gè)輸出的結(jié)果:

true false [com.ubs.sae.test.HashTest@1, com.ubs.sae.test.HashTest@1] 

以上這個(gè)示例,我們只是重寫了hashCode方法,從上面的結(jié)果可以看出,雖然兩個(gè)對(duì)象的hashCode相等,但是實(shí)際上兩個(gè)對(duì)象并不是相等;,我們沒(méi)有重寫equals方法,那么就會(huì)調(diào)用object默認(rèn)的equals方法,是比較兩個(gè)對(duì)象的引用是不是相同,顯示這是兩個(gè)不同的對(duì)象,兩個(gè)對(duì)象的引用肯定是不定的。這里我們將生成的對(duì)象放到了HashSet中,而HashSet中只能夠存放唯一的對(duì)象,也就是相同的(適用于equals方法)的對(duì)象只會(huì)存放一個(gè),但是這里實(shí)際上是兩個(gè)對(duì)象a,b都被放到了HashSet中,這樣HashSet就失去了他本身的意義了。
此時(shí)我們把equals方法給加上:

public class HashTest {   private int i;    public int getI() {     return i;   }    public void setI(int i) {     this.i = i;   }    <span style="color:#3366FF;"><strong>public boolean equals(Object object) {     if (object == null) {       return false;     }     if (object == this) {       return true;     }     if (!(object instanceof HashTest)) {       return false;     }     HashTest other = (HashTest) object;     if (other.getI() == this.getI()) {       return true;     }     return false;   }</strong></span>    public int hashCode() {     return i % 10;   }    public final static void main(String[] args) {     HashTest a = new HashTest();     HashTest b = new HashTest();     a.setI(1);     b.setI(1);     Set<HashTest> set = new HashSet<HashTest>();     set.add(a);     set.add(b);     System.out.println(a.hashCode() == b.hashCode());     System.out.println(a.equals(b));     System.out.println(set);   } } 

此時(shí)得到的結(jié)果就會(huì)如下:

true true [com.ubs.sae.test.HashTest@1] 

從結(jié)果我們可以看出,現(xiàn)在兩個(gè)對(duì)象就完全相等了,HashSet中也只存放了一份對(duì)象。

總結(jié)
1、hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用來(lái)在散列存儲(chǔ)結(jié)構(gòu)中確定對(duì)象的存儲(chǔ)地址的;

2、如果兩個(gè)對(duì)象相同,就是適用于equals(java.lang.Object) 方法,那么這兩個(gè)對(duì)象的hashCode一定要相同;

3、如果對(duì)象的equals方法被重寫,那么對(duì)象的hashCode也盡量重寫,并且產(chǎn)生hashCode使用的對(duì)象,一定要和equals方法中使用的一致,否則就會(huì)違反上面提到的第2點(diǎn);

4、兩個(gè)對(duì)象的hashCode相同,并不一定表示兩個(gè)對(duì)象就相同,也就是不一定適用于equals(java.lang.Object) 方法,只能夠說(shuō)明這兩個(gè)對(duì)象在散列存儲(chǔ)結(jié)構(gòu)中,如Hashtable,他們“存放在同一個(gè)籃子里”。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鹤山市| 盈江县| 高青县| 武川县| 东丽区| 黔西县| 星座| 定边县| 巫山县| 郸城县| 苏州市| 乳山市| 邯郸县| 巴彦淖尔市| 鲜城| 平利县| 建宁县| 唐海县| 师宗县| 揭西县| 宁安市| 迭部县| 高青县| 安仁县| 赣榆县| 察雅县| 兰西县| 武冈市| 观塘区| 辽中县| 荣成市| 安庆市| 高淳县| 永年县| 祁阳县| 定西市| 静安区| 湘潭县| 治多县| 永济市| 常熟市|