2011-09-27 21 views
1

等於我有這個類:實現與套裝

private static class ClassA{ 
int id; 
String name; 

public ClassA(int id, String name){ 
    this.id= id; 
    this.name = name; 
} 

@Override 
public boolean equals(Object o) { 
    return ((ClassA)o).name.equals(this.name); 
} 

}

爲什麼這主要是打印2元,如果我重寫方法等於在ClassA的比較只有名稱?

public static void main(String[] args){ 
    ClassA myObject = new ClassA(1, "testing 1 2 3"); 
    ClassA myObject2 = new ClassA(2, "testing 1 2 3");  

    Set<ClassA> set = new HashSet<ClassA>(); 
    set.add(myObject); 
    set.add(myObject2); 
    System.out.println(set.size()); //will print 2, but I want to be 1! 
} 

如果我期待進入設置Java documentation

不包含重複元素的集合。更正式地,集合不包含e1和e2這樣的元素對,使得e1.equals(e2)和至多一個空元素。正如它的名字所暗示的,這個接口模擬數學集抽象。

所以顯然我只需要重寫equals,但是我聽說我也要重寫hashcode,但是爲什麼?

回答

7

他們有不同的散列,因爲你沒有重寫hashCode。這意味着他們被放在HashSet中的兩個不同的桶中,所以他們從來沒有得到比較與平等首先。

我想補充,因爲它不是在使用

public int hashCode() { 
    return name.hashCode(); 
} 

公告ID未在使用的hashCode等於無論是。 (PS我也想指出有一個不用平等的id的諷刺,這很有趣,通常情況是相反:id是唯一的等於!)

+1

*具有未在等號中使用的ID的諷刺*:[有時](http://community.jboss.org/wiki/EqualsAndHashCode)它是實際上是一個好習慣 –

3

因爲您也沒有覆蓋hashCode()

程序員應該注意的是,它覆蓋Object.equals方法還必須重寫Object.hashCode方法,以滿足對Object.hashCode方法一般合同中的任何類。特別是,c1.equals(c2)意味着c1.hashCode()==c2.hashCode()

http://download.oracle.com/javase/6/docs/api/java/util/Collection.html

和:

hashCode的一般合同是:

  • 每當它是一個Java的執行期間,在同一對象不止一次調用應用程序中,只要對象的equals比較中沒有使用的信息是mo,hashCode方法就必須始終返回相同的整數dified。該整數不需要從應用程序的一次執行到同一應用程序的另一次執行保持一致。

  • 如果兩個對象根據equals(Object)方法相等,則對兩個對象中的每個對象調用hashCode方法必須產生相同的整數結果。

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

http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode()