2011-03-26 72 views
9

我明白爲什麼爲兩個相同的對象(通過equals)提供相同的散列碼很重要。但反之亦然,如果兩個對象具有相同的哈希碼,它們必須相等嗎?合同是否仍然成立?我找不到可能發生這種情況的示例,因爲如果所有參與equals方法的屬性都被用於重寫hashcode方法,那麼我們始終會使用相同的對象的相同hashcode。請給出意見。具有相同哈希碼的兩個Java對象不一定相等嗎?

+1

見http://stackoverflow.com/questions/ 4360035/why-hashcode-can-return-the-same-value-for-different-objects-in-java – esaj 2011-03-26 15:05:42

回答

27

如果兩個對象具有相同的哈希碼,則它們不一定相等。否則,你會發現完美的散列函數。但情況正好相反 - 如果對象相同,則它們必須具有相同的哈希碼。

+5

+1這與散列對象一般也不相關,不僅僅是java對象。 – MByD 2011-03-26 15:08:19

+0

考慮這個[示例](http://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html)在這裏'firstBook'和'secondBook'有不同的hashcode。所以你的陳述是真實的'如果對象相同,那麼他們有相同的哈希碼' – Fresher 2014-05-21 13:10:03

+1

多麼愚蠢的答案......他似乎沒有回答爲什麼? – anshulkatta 2014-06-02 19:42:20

4

根據在Javadoc:http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29

不需要它,如果兩個對象根據equals不相等(java.lang.Object)方法,則調用每個兩者的hashCode方法對象必須產生不同的整數結果。但是,程序員應該意識到,爲不相等的對象生成不同的整數結果可能會提高哈希表的性能。

編輯:在現實世界中,兩個字符串可能具有相同的哈希碼。例如,如果要存儲長度爲10的所有包含小寫英文字母的字符串組合(如「aaaaaaaaaa」,「aaaaaaaaab」等),則不能爲每個141.167.095.653分配一個唯一的哈希碼。 376個組合,因爲Java中的int是32位,因此最多可以有4.294.967.296個不同的值。

2

事實上

public int hashCode(){ 
    return 1; 
} 

的問題是一個有效的哈希碼實現......但可怕之一。將使所有的哈希表緩慢。 但是,您可以擁有兩個具有相同哈希碼的不同對象。但是這不應該是一般情況,真正的實現應該在大多數情況下爲不同的值提供不同的哈希碼。

+0

這是一個有效的論點。哈希代碼必須滿足以確保正確性的唯一屬性是哈希代碼應該不同*只有*如果底層數據結構不同。這是因爲不同的哈希碼在設計上意味着不同的基礎結構。 – Jasim 2012-09-25 07:37:59

+0

你是什麼意思的「不同的基礎結構」? – NoName 2017-06-24 06:27:27

2

奇怪的是,NumberFormat的是這違反,該建議一個Java基礎類的一個示例:

多達是合理可行,通過 類對象定義的hashCode方法並返回不同的整數爲不同的對象。

下面是一些代碼,至少在Java的版本下我目前在Mac OS X 10.6下運行。

Numberformat nf = NumberFormat.getNumberInstance(); 
NumberFormat nf2 = NumberFormat.getNumberInstance(); 
assert nf != nf2; // passes -- they are different objects 
assert !nf.equals(nf2); // passes -- they are not equal 
assert nf.hashCode() != nf2.hashCode(); // fails -- same hash code 
1

hashCode值取決於實施。例如String類根據值實現hashCode()函數。這意味着

String a=new String("b"); 
String b=new String("b"); 

將有相同hashcode但是,這是兩個不同的對象。 a==b將返回false

4

hashCode函數的作用是允許對象快速分割成已知不同於其自身集外的所有項目的集合。假設一個人擁有1,000個項目,並將其分成十個大致相等大小的集合。撥打hashCode的一個電話可以快速識別該物品不等於900個物品,而不必在這些物品上使用equals。即使必須使用equals將該項目與其他100個項目進行比較,這仍然只是將其與所有1000個項目進行比較的成本的1/10。實際上,即使在大量收集中,hashCode通常也會消除99.9%或更多的不相等項目,最多隻有少數人被檢查。

0

哈希碼方法返回整數。如果整數範圍結束,那麼兩個不同的對象也將具有相同的散列碼。所以不需要兩個不同的對象具有相同的哈希碼。

0

爲了證明,如果兩個對象具有相同的 的hashCode並不意味着他們是平等的

說你有兩個用戶定義的類

class Object1{ 
     private final int hashCode = 21; 
     public int hashCode(){ 
      return hashCode; 
     } 

     public boolean equals(Object obj) { 
      return (this == obj); 
     } 
    } 

    class Object2{ 
     private final int hashCode = 21; 
     public int hashCode(){ 
      return hashCode; 
     } 

     public boolean equals(Object obj) { 
      return (this == obj); 
     } 
    } 

    Object1 object1 = new Object1(); 
    Object2 object2 = new Object2(); 

    Object1 object3 = new Object1(); 


    if(object1.hashCode() == object2.hashCode()){ 
     // return true, because the hashcodes are same 
    } 

    but 
    if(object1.equals(object3)){ 
      // will fail, because two different objects 
    } 
相關問題