2014-07-06 89 views
0

所以這是從頭部的第一個Java(頁563)的hashCode平等對象

的默認行爲()是產生堆上每個對象一個唯一的整數 。 因此,如果您不覆蓋類中的hashCode(),則不會認爲該類型的兩個對象相等。

但一個簡單的測試將反駁這個我認爲。

public class Song { 

    private String name; 

    public Song(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 


    @Override 
    public boolean equals(Object obj) { 
     Song objectSong = (Song) obj; 
     return this.getName().equals(objectSong.getName()); 
    } 

} 

嗯,這將返回true:

Song songA = new Song("A","B"); 
Song songB = new Song("A","C"); 

System.out.println(songA.equals(songB)); 

我這麼想嗎?這本書試圖告訴我什麼?

+0

就在你引用它的部分之前說「如果你重寫equals(),你必須重寫hashCode()」。 – Robert

+0

@Robert對不起,我不明白,你有什麼想告訴這個評論? –

+0

在頁563上它說:「如果你重寫equals(),如果你不重寫hashCode(),你必須重寫hashCode()」**和**「,沒有兩個對象可以被認爲是相等的。所以如果你不重寫hashCode(),你不能覆蓋equals(),因此不能認爲兩個對象是相等的。 – Robert

回答

2

hashCode()的默認行爲是生成用於在堆上的每個對象的唯一整數 。因此,如果您不覆蓋類中的hashCode(),則不會將這種類型的兩個對象視爲相等。

你是在誤解。作者並不是說一種方法(即所有的equalshashCode)都不能爲兩個不同的對象返回true。他們說,語義上如果兩個對象的hashCode的結果不相等,則不應認爲這兩個對象相等。他們正在描述如何使用hashCode。如果你以不同的方式使用它,你可能會得到奇怪和意想不到的結果。

+0

+1。例如'HashSet'只考慮*調用匹配散列碼的對象的equals。只要散列碼不匹配,它們無論如何都不可能相等。 – Robert

1

您需要重寫散列碼,以便該類的行爲與基於散列碼的集合(以及其他任何內容)的預期相同。

例如,如果您將您的歌放在HashSet中,然後嘗試放入另一個,會發生什麼情況?

如果覆蓋等於,則應該始終覆蓋Hashcode,反之亦然。確保它們一致。

(喬希布洛赫有效的Java,是一個很好的起點)

0

在Java中,每個對象都有訪問equals()方法,因爲它是 從Object類繼承。但是,這個默認實現 只是簡單地比較對象的內存地址。您可以使用 覆蓋 java.lang.Object中定義的equals()方法的默認實現。如果你重寫equals(),你必須重寫 hashCode()。否則,違反總體合同 Object.hashCode將發生,當您的類與所有基於散列的集合結合使用時,可能會產生意想不到的影響 。

來源:http://www.xyzws.com/javafaq/why-always-override-hashcode-if-overriding-equals/20(看看它,它有很好的例子)。

結論:您只需要覆蓋equals進行簡單比較。但是,對於其他方面,例如基於哈希的集合,您應該也覆蓋hashCode