2013-10-03 175 views
1

我試圖用我的類Cell作爲關鍵使用一個HashMap。但是,將項目放入HashMap之後,包含該項目的調用將返回false。HashMap不返回基於密鑰的值

public static void main(String args[]) { 
     HashMap<Cell, String> map = new HashMap<Cell, String>(); 
     map.put(new Cell(0,0), "Bob"); 
     System.out.println(map.containsKey(new Cell(0,0))); 
     System.out.println(new Cell(0,0).equals(new Cell(0,0))); 
} 

此打印出虛實,它應打印真實,真實的,因爲根據地圖文檔中的containsKey使用.equals()。我究竟做錯了什麼?

+10

您還需要正確實現'hashCode()'。 –

+0

或者根本不實現equals,hashCode。如果你重寫equals,你也應該實現hashCode – Anton

+1

如果你不重寫'hashCode()',那麼它只會使用默認的Object方法,這就是爲什麼它們每個對象都不同,儘管它們具有相同的值。 –

回答

3

這很可能是因爲您沒有執行equals()hashCode()。在Java中,經驗法則是如果你實現了一個,你必須實現另一個。在你的情況下,這是強制性的,因爲HashMap使用它們。

您使用兩個單獨的地址創建了兩個單獨的對象。如果沒有這些方法,JVM無法知道對象是「相同的」。

請參閱http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()

1

考慮如何實現HashMap。放置時,它首先計算對象hashCode()以確定將對象放入哪個存儲桶。當它嘗試檢索對象時,它會再次獲取其hashCode(),標識爲目標存儲分區,通過存儲分區中的鏈接列表,調用equals()針對每個對象。如果它找到匹配則返回。

換句話說,當您使用HashMap時,您需要有一個正確的和匹配的執行equals()hashCode()

Object繼承的默認hashCode()方法不能正確返回相同的hashCode(),除非對象引用是相同的。在你的情況下,他們不是。

0

幾次調用新的Cell(0,0)產生具有不同哈希碼的不同對象。你應該爲Cell類實現hashCode。

0

您可能忘記爲Cell實施hashcode()功能,這也是爲了在HashMap中使用用戶定義的類所必需的。這裏是實現hashcode()功能簡單,一般準確的方法:

int hashcode(){ 
    return (field1.toString()+field2.toString()+...+fieldN.toString()).hashcode(); 
} 

field1fieldN在你的類中的字段。如果這些字段是主要字段(即int),只需取出toString()即可。