2013-02-15 77 views
1

爲什麼它達不到印刷生產線「在這裏」?換句話說,爲什麼它不使用我重寫的equals? 在此先感謝類沒有使用覆蓋等於

import java.util.*; 
class NumberClass extends Object{ 
    private int number; 

    public NumberClass(int n){ 
     number=n; 

    } 
    @Override 
    public boolean equals(Object other){ 
     System.out.println("here"); 
     return false; 
    } 
    @Override 
    public String toString(){ 

     return number+""; 
    } 
} 
public class HelloWorld { 
    public static void main(String[] args) { 

     Set <NumberClass> set= new HashSet<NumberClass>(); 
     set.add(new NumberClass(0)); 
     set.add(new NumberClass(0)); 
     System.out.println(set); 
    } 

} 

回答

4

這是因爲HashSet使用哈希代碼來測試對象是否已經在集合和僅使用equals如果有碰撞。對象的默認散列碼是內部ID,所以只是因爲兩個對象相等並不意味着它們具有相同的散列碼。在這種情況下,顯然不是一個衝突,所以沒有必要爲HashSet調用equals

這就是爲什麼你應該總是覆蓋hashCode當你重寫equals。有關此主題的更多信息,請參閱this article。您應該編寫一個hashCode方法,該方法爲equals的對象返回相等的散列值。例如:

public int hashCode() { 
    return number; 
} 

hashCode總的要求是,滿足equals()對象應返回相同的散列碼。請注意,不要求測試equals()失敗的對象具有不同的哈希碼。如果你返回一個常數(就像Jayamohan所建議的那樣),它滿足hashCode合同;然而,這將完全消除使用HashSet的好處,你也可以使用簡單的ArrayList

+0

所以它不使用equals方法,而是使用某種形式的哈希碼? – Sammy 2013-02-15 04:28:23

+0

@Sammy - 的確如此。如果兩個對象散列到同一個存儲桶,它只會使用「equals」。這是哈希表(和哈希集合)如此高效的一部分 - 它們不必測試集合中大多數(通常是任何)元素的平等性。 – 2013-02-15 04:29:32

1

在比較的對象,

  • equals方法將如果的hashCode不同被稱爲
  • hashCode方法將被稱爲IF(OBJ1 == OBJ2)

所以你的情況,因爲你還沒有覆蓋hashCode方法的哈希ç頌歌是不同的,所以等於沒有被調用。嘗試覆蓋下面的hashCode方法,你的equals方法將被調用。在Java中

@Override 
public int hashCode() { 
    return 1; 
} 

Object.equals API狀態,如下

注意,一般需要重寫hashCode方法 每當這個方法被覆蓋,以保持hashCode方法一般 合同,其中規定相同的對象必須有 具有相同的散列碼。

所以記得在重寫equals方法時覆蓋hashCode