2012-07-12 53 views
0

我有一類,其中包含兩個字段,年齡(INT),並名稱(字符串)。在eclipse中,我重寫了hashCode()等於()方法與這兩個字段。我還創建了一個比較器基於年齡字段。Java的設置不能區分不同對象

現在,我創建一個比較的年齡一個TreeSet的對象,也類的兩個實例(具有不同字段的值)。然後我將這兩個對象添加到集合中,但是,集合中總是隻有一個對象。

爲了解這個問題,我打印出這兩個對象的散列值,發現它們是不同的。然後,我測試他們的等於()方法,它確實輸出錯誤當我比較具有不同字段值的兩個實例。所以現在,我不知道爲什麼TreeSet無法處理(區分)的問題。任何人都可以給我一些幫助嗎?非常感謝 !

回答

4

TreeSet根本不使用hashCode()equals()。它使用您傳遞的參數作爲參數(如果它們是Comparable且不提供比較器,則使用對象的方法compareTo())。如果compare()(或compareTo())在比較這兩個對象時返回0,TreeSet將認爲兩個對象相等。

因此,如果您的比較器只比較人類的年齡,那麼所有年齡相同的人將被視爲相等。如果你想人被視爲相等時,它們具有相同的年齡和名字,然後比較應按年齡比較,然後通過名稱比較,如果年齡比較返回0

+0

是的,有斑點。在你的compareTo()方法中使用這兩個字段。你想按年齡排序,所以在年齡內按名字排序,然後2個相同年齡的名字仍然會被正確排序,但不會被認爲是平等的(即你的compareTo將與等號一致)。 – MattR 2012-07-12 14:16:59

+0

但是在Java文檔中,** Comparator **接口只有** compare()**方法,而不是** compareTo()**,不是嗎? – 2012-07-12 14:21:53

+0

是的。但是,如果您的對象實現了Comparable,則不需要將比較器傳遞給TreeSet的構造函數。在這種情況下,TreeSet將使用它們的「compareTo」方法比較對象。 – 2012-07-12 14:24:22

2

From the documentation

這是因爲Set接口是根據等於 操作定義的,但TreeSet實例使用其compareTo(或compare)方法執行所有元素比較 ,所以從該方法看,通過此方法認定爲相等的兩個元素是該套, 相等。即使它的排序是 與等號不一致,集合的行爲也是明確定義的;它只是不服從Set界面的一般合約 。