2011-08-29 76 views
0

我有一個HashMap將我的Context類的對象映射到Integers。在Context類中,我確實覆蓋了java.lang.Object的public int hashCode()和public boolean equals(Object c)。然而,我有迭代的問題:Java:HashMap聲稱它有密鑰,但某種程度上沒有

我想要(例如)獲取分配給每個上下文對象的整數值,所以我遍歷整個地圖的鍵集。但是,這是行不通的,因爲地圖上說,它沒有指定的鍵:

for (Context to : map.keySet()) { 
    System.out.println("to-hash: " + to.hashCode()); 
    System.out.println("first-hash: " + map.keySet().iterator().next().hashCode()); 
    System.out.println("hashs equal: " + (to.hashCode()==map.keySet().iterator().next().hashCode())); 
    System.out.println("to equals first: " + to.equals(map.keySet().iterator().next())); 
    System.out.println("map has to? " + map.containsKey(to)); 
} 

輸出是

to-hash: 156349 
first-hash: 156349 
hashs equal: true 
to equals first: true 
map has to? false 

從我的理解是,當給定一個鍵,地圖首先檢查哈希碼是否匹配,然後檢查是否相等。這兩種情況都是這種情況,'to'對象的散列碼和密鑰集中的第一個對象匹配,它們也是相等的。有趣的是,當我將hashCode()函數的返回值更改爲一個常量(雖然不推薦出於性能原因,該常量是有效的),但它可以工作。但我不明白爲什麼這會有所作爲,因爲156349 == 156349就像7 == 7一樣。

我很困惑,我害怕我錯過了一些非常明顯的東西,只是看不到它。如果是這樣的話,對我感到羞恥,但仍然,我會感激提示:-)

非常感謝!

+0

我應該指出,鍵集中只有一個元素,並且我知道集存儲元素沒有特定的順序:-) – bufferUnderrun

+2

請發佈您的hashCode和equals的覆蓋,因爲這可能是問題所在(可疑這是你的平等 - 也許你的定義與a == b不一樣b == a?) – antlersoft

回答

9

這可能發生,如果你Context對象是在影響的哈希碼的方式可變的,如果你執行這改變了哈希碼後把它在地圖上的操作。地圖只會在插入點處記錄hashCode()的值,然後在您嘗試查找特定鍵時使用它來查找匹配項。

如果你使散列函數恆定,這將與它一致。基本上,你不應該在將哈希鍵放入地圖之後進行變異。

當然,這只是猜想,但它確實符合症狀。

+0

+1。請發佈您的代碼'上下文'。 –

相關問題