2012-03-19 24 views
5

編輯:現在正確解釋問題。我可以將HashSets作爲HashMap中的鍵嗎?如果不是,建議替代方案

我有一個散列圖,我想存儲在一起看到的單詞集合(鍵)和它們在一起看到的行(值)。這是我想出了一個結構:

HashMap<HashSet<String>, HashSet<Integer>> hm= ... 

爲輸入:

  1. 芒果,香蕉,蘋果

  2. 蘋果,香蕉

  3. 桃,海象

  4. 海象,桃子

當我一行一行閱讀這篇文章時,我從行中的單詞組合中創建了新的臨時密鑰(尚未插入到散列表中的哈希集)。每個臨時密鑰都是該行中單詞的子集的哈希集。如果臨時密鑰在我的HashMap中,已經存在我的

if(hashmap.containsKey(hashset)) 

檢查我只需將新的行添加到該鍵的對應值,如果沒有,我做的HashMap中的新條目,並照顧它。

在任何時候我都不會更改現有的密鑰。我只更新了它們在hasmmap中的相應值。

我的HashMap,在讀取文件末尾,應該是這個樣子

[蘋果,香蕉] = [1,2]

[桃,海象] = [3,4]

...

的問題是,

if(hashmap.containsKey(hashset)) 

一段代碼不ALW ays檢測現有密鑰。爲什麼是這樣?這個結構不允許嗎?

謝謝

+1

您是否嘗試過它呢? – pcalcao 2012-03-19 16:23:27

+0

第5行不會映射到「桃子,海象」嗎?那麼芒果呢? – Thomas 2012-03-19 16:25:34

+0

@pcalcao是的。它表現奇怪。有時它會檢測到該設置存在,有時不會。我只想驗證HashMap是否可以處理哈希集有一個關鍵。 – student101 2012-03-19 16:25:45

回答

3

可以,但一旦你加入了HashSet作爲關鍵,HashMap你不應該再次進行修改,爲HashSet.hashCode()可能會改變,你將永遠不會再找到你HashSet。換句話說,如果你正在做這樣的事情,請確保您的密鑰是不可變的HashSets(見Matt's answer here

另一種方法是使用沿着MultiKeyMapMultiKeycommons collections

+0

+1,但爲什麼他應該使用替代方案?他可以在'hashset'中覆蓋'equals'和'hashcode' – Cratylus 2012-03-19 16:41:05

+0

@ user384706:OP詢問可能的替代方案 – 2012-03-19 16:41:36

+0

好的,但他可以只擴展'hashset' 。我想不出爲什麼它不夠用的原因 – Cratylus 2012-03-19 16:42:44

8

這應該工作,但你需要注意鑰匙的可變性。如果你改變其中一個鍵的內容,它的哈希碼將會改變,你的地圖會開始做奇怪的事情。根據JavaDoc爲Map

注意:如果使用可變對象作爲地圖 按鍵很大,一定要小心。如果對象 的值以影響等於比較的方式進行更改,而 對象是地圖中的關鍵字,則未指定地圖的行爲。這種禁令的一個特例是 地圖不允許自己作爲關鍵字。儘管 對於包含自身值的地圖是允許的,但建議您謹慎使用 :在這樣的地圖上,不再定義equals和hashCode方法 。

爲了避免這種情況,在創建時立即換用Collections.unmodifiableSet()鍵,或只是使用ImmutableSet番石榴。

+0

+1對於提到的地圖Javadoc – 2012-03-19 16:38:25

+0

@matt嗨,我已經改變了現在的問題。這個問題沒有很清楚的解釋。在任何時候,我都不會更改密鑰,我只更新指向hashmap中的值。 – student101 2012-03-19 17:20:53

1

你的問題已經由@Lukas ans @Matt很好的解釋了。
我認爲你可以通過使用擴展或使用修飾器模式來創建一個​​,以獨立於內容的方式覆蓋equalshashCode

這樣就可以避免引入第三方jar文件的依賴只是針對特定問題

+0

這是一個有趣的選擇!從OP的文本中很難看出它是否會產生想要的結果,儘管... – 2012-03-19 16:56:03

+0

我只是想知道是否有一些我沒有看到的陷阱。恕我直言,如果你不真的使用它們,避免引入額外的庫是很好的 – Cratylus 2012-03-19 17:00:47

相關問題