2012-04-17 195 views
0

,同時通過凱西塞拉利昂的書要我碰到這個代碼片段跌跌撞撞:散列函數和密鑰

m.put("k1", new Dog("aiko")); // add some key/value pairs 
m.put("k2", Pets.DOG); 
m.put(Pets.CAT, "CAT key"); 
Dog d1 = new Dog("clover"); 
m.put(d1, "Dog key"); 
m.put(new Cat(), "Cat key"); 

地圖是用來儲存東西在鍵和值格式。當我們輸入「k1」或新的Cat()作爲關鍵字時,有人會告訴我實際存儲在密鑰中的內容嗎?是否存儲對這些對象的引用或散列碼的值?我完全同意這一點。請指教。

如果您能指引我閱讀更多的閱讀材料,我們將不勝感激。

回答

0

它將由您的對象定義。

您必須創建一個hashCode()和一個equals()方法,以便它可以存儲在您的散列表中。

儘管合理實際,類Object定義的hashCode方法確實爲不同的對象返回不同的整數。 (這一般是通過將該對象的內部地址轉換成一個整數來實現的,但不是由的JavaTM編程語言不需要這種實現技巧。)

參見在java.lang.Object中http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#hashCode(Javadoc中)

,或者你可以閱讀這一個解釋 http://www.javaworld.com/javaworld/javaqa/2002-06/01-qa-0621-hashtable.html

我希望它能幫助

2

該地圖是N個桶的陣列。

put()方法首先在您的密鑰上調用hashCode()。從這個哈希碼中,它使用一個模來獲得地圖中桶的索引。

然後,它遍歷存儲在與找到的存儲桶關聯的鏈接列表中的條目,並使用equals()方法將每個條目關鍵字與您的關鍵字進行比較。

如果一個條目具有與您的密鑰相同的密鑰,則其值由新值替換。否則,將使用新密鑰和新值創建一個新條目,並將其存儲在與存儲桶關聯的鏈接列表中。

由於Cat實例和String實例永遠不會相等,因此與String關鍵字關聯的值將永遠不會通過將與Cat關聯的值進行修改。

0

當使用HashMap時,其中的鍵是唯一的。在Java中,根據equals()和hashCode()方法的定義檢查這些鍵的唯一性,即所考慮的對象的類所提供的類。

這是通過首先比較使用equals()方法並且如果它返回相等然後使用hashCode()進行比較來完成的。另外,你必須知道指向一個對象的每個引用都有一個位模式,對於引用同一對象的多個引用可能不同。

因此,一旦equals()測試通過,對象將不會插入到地圖中,因爲地圖應該具有唯一的鍵。因此,作爲映射關鍵字的對象的每個hashCode值將爲一系列hashCode值形成不同的桶,並且該對象將相應地分組。

EDIT提供一種例如:

例如,讓我們考慮兩個對象具有值「你好」和「hlleo」的字符串的屬性,並假設哈希碼()函數被編程爲使得對象的散列碼是String屬性中字符的ASCII值的總和,如果String屬性的值相等,則equals()方法返回true。

因此,在上述情況下,equals()返回false,因爲字符串不相等,但hashCode將相同。所以這兩個對象將被放置在相同的散列碼桶中。

希望有所幫助。

+0

這顯然是錯誤的。平等僅限於等同。 hashCode用於減少潛在的相等候選數。兩個相等的對象必須具有相同的hashCode。 – 2012-04-17 15:46:49

+0

這是正確的,但你的回答說equals首先被調用,然後如果equals返回true,則使用hashCode。這完全不正確。閱讀我的答案,瞭解它是如何工作的。 – 2012-04-17 18:08:58

+0

那麼,是不是它先hashCode()然後equals()?糾正我,如果我錯了。非常感謝您更新我的知識。 – TechSpellBound 2012-04-17 18:26:18