詳解Java頂用於查找對象哈希碼值的hashCode()函數。本站提示廣大學習愛好者:(詳解Java頂用於查找對象哈希碼值的hashCode()函數)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解Java頂用於查找對象哈希碼值的hashCode()函數正文
懂得
hashCode() 的感化是獲得哈希碼,也稱為散列碼;它現實上是前往一個int整數。這個哈希碼的感化是肯定該對象在哈希表中的索引地位。
hashCode() 界說在JDK的Object.java中,這就意味著Java中的任何類都包括有hashCode() 函數。
固然,每一個Java類都包括hashCode() 函數。然則,僅僅當創立並某個“類的散列表”(關於“散列表”見上面解釋)時,該類的hashCode() 才有效(感化是:肯定該類的每個對象在散列表中的地位;其它情形下(例如,創立類的單個對象,或許創立類的對象數組等等),類的hashCode() 沒有感化。
下面的散列表,指的是:Java聚集中實質是散列表的類,如HashMap,Hashtable,HashSet。
也就是說:hashCode() 在散列表中才有效,在其它情形下沒用。在散列表中hashCode() 的感化是獲得對象的散列碼,進而肯定該對象在散列表中的地位。
我們都曉得,散列表存儲的是鍵值對(key-value),它的特色是:能依據“鍵”疾速的檢索出對應的“值”。這個中就應用到了散列碼!
散列表的實質是經由過程數組完成的。當我們要獲得散列表中的某個“值”時,現實上是要獲得數組中的某個地位的元素。而數組的地位,就是經由過程“鍵”來獲得的;更進一步說,數組的地位,是經由過程“鍵”對應的散列碼盤算獲得的。
上面,我們以HashSet為例,來深刻解釋hashCode()的感化。
假定,HashSet中曾經有1000個元素。當拔出第1001個元素時,須要怎樣處置?由於HashSet是Set聚集,它許可有反復元素。
“將第1001個元素逐一的和後面1000個元素停止比擬”?明顯,這個效力是相等低下的。散列表很好的處理了這個成績,它依據元素的散列碼盤算出元素在散列表中的地位,然後將元素拔出該地位便可。關於雷同的元素,天然是只保留了一個。
由此可知,若兩個元素相等,它們的散列碼必定相等;但反過去確紛歧定。在散列表中,
1、假如兩個對象相等,那末它們的hashCode()值必定要雷同;
2、假如兩個對象hashCode()相等,它們其實不必定相等。
留意:這是在散列表中的情形。在非散列表中必定如斯!
示例
我們來看一個詳細的示例吧,
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); } }
這個輸入的成果:
true false [com.ubs.sae.test.HashTest@1, com.ubs.sae.test.HashTest@1]
以上這個示例,我們只是重寫了hashCode辦法,從下面的成果可以看出,固然兩個對象的hashCode相等,然則現實上兩個對象其實不是相等;,我們沒有重寫equals辦法,那末就會挪用object默許的equals辦法,是比擬兩個對象的援用是否是雷同,顯示這是兩個分歧的對象,兩個對象的援用確定是不定的。這裡我們將生成的對象放到了HashSet中,而HashSet中只可以或許寄存獨一的對象,也就是雷同的(實用於equals辦法)的對象只會寄存一個,然則這裡現實上是兩個對象a,b都被放到了HashSet中,如許HashSet就掉去了他自己的意義了。
此時我們把equals辦法給加上:
public class HashTest { private int i; public int getI() { return i; } public void setI(int i) { this.i = i; } <span ><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); } }
此時獲得的成果就會以下:
true true [com.ubs.sae.test.HashTest@1]
從成果我們可以看出,如今兩個對象就完整相等了,HashSet中也只寄存了一份對象。
總結
1、hashCode的存在重要是用於查找的快捷性,如Hashtable,HashMap等,hashCode是用來在散列存儲構造中肯定對象的存儲地址的;
2、假如兩個對象雷同,就是實用於equals(java.lang.Object) 辦法,那末這兩個對象的hashCode必定要雷同;
3、假如對象的equals辦法被重寫,那末對象的hashCode也盡可能重寫,而且發生hashCode應用的對象,必定要和equals辦法中應用的分歧,不然就會違背下面提到的第2點;
4、兩個對象的hashCode雷同,其實不必定表現兩個對象就雷同,也就是紛歧定實用於equals(java.lang.Object) 辦法,只可以或許解釋這兩個對象在散列存儲構造中,如Hashtable,他們“寄存在統一個籃子裡”。