程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 詳解Java頂用於查找對象哈希碼值的hashCode()函數

詳解Java頂用於查找對象哈希碼值的hashCode()函數

編輯:關於JAVA

詳解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,他們“寄存在統一個籃子裡”。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved