2013-06-19 25 views
0

是否有可能創建一個密鑰是一個集合(任何類型的集合)的地圖?創建一個集合作爲關鍵的地圖?

如果我在最常見的集合上嘗試它,我被告知該集合不能轉換爲可比較的集合。

我一直在努力爲自定義集合寫一個compareTo函數,但我掙扎着。

要麼我需要寫compareTo,要麼我需要找到一個預製Map來接受Maps所接受的collections/Collection。

如何將集合用作地圖上的鍵?我已經看過堆棧溢出,我已經多次搜索這個問題,但我從來沒有找到一個可靠的解決方案!


我想這樣做的原因是我寫了一個模擬卡洗牌的「混洗」模擬。我希望能夠計算特定手(作爲集合建模)出現的次數。這將是這個樣子:

H4,C3,D2: 8 
    H9,D6,S11: 10 
    ...... 
+1

爲什麼要使用一個集合作爲首位關鍵? Map背後的整個概念是不可變的鍵,集合直接違反了這個概念。 –

+0

這不是一個好主意,除非集合是隻讀的,它們可能會改變,結果改變了equals和hashCode的行爲,並且很可能給出結果很難預測什麼時候檢查if密鑰已經存在或者在地圖中檢索密鑰的同時。 –

+0

您可以使用ArrayList的toString方法來使用String作爲鍵,或者您可以使用自定義格式化程序爲您創建一個字符串,每次追加到字符串時都需要刪除舊字符串的條目。 – phntmasasin

回答

10

是否有可能創建一個地圖,關鍵是一個集合(任何種類的集合)?

是的,這是可能的,但絕對不推薦。如果你的集合改變了,它的哈希碼很可能也會改變,這可能會導致令人驚訝的行爲。

Map's javadoc

注意:如果使用可變對象作爲map的key很大,一定要小心。如果對象的值以影響等於比較的方式更改,而對象是地圖中的關鍵字,則不會指定地圖的行爲。


如果我嘗試在最常見的收藏我告訴收集不能被轉換爲相媲美。

除非使用排序映射,即TreeMap,否則該關鍵不需要具有可比性。使用一個簡單的HashMap,你不會有問題。


按照你的編輯,我將創建一個新的不可改變的手工類:

class Hand implements Comparable<Hand> { 
    private final List<Card> cards; 
    Hand(Card c1, Card c2, Card c3) { 
     cards = Collections.unmodifiableList(Arrays.asList(c1, c2, c3)); 
    } 
    //getters, no setters 
    //implement compareTo 
} 

和實施compareTo如果你想在一個TreeSet<Hand, Integer>和排序手部力量,例如使用它。

+0

同意必須小心確保密鑰在被用作密鑰時不會改變。 –

+0

可以通過使用「不可修改」集合作爲關鍵點來緩解這種擔憂嗎? –

+0

@tieTYT您只需確保不要修改密鑰。一個不可修改的集合將強制執行該操作。 – assylias

2

是的,你可以使用任何集合作爲關鍵。如果你想要像TreeMap一樣的SortedMap,你必須提供一個比較器來確定順序。但是,如果您使用任何類型的HashMap,則不需要。

Map<List<Integer>, String> map = new HashMap<>(); 
map.put(Arrays.asList(1,2,3), "one to three"); 
map.put(Arrays.asList(7,8,9), "seven eat nine"); 
System.out.println(map); 

打印

{[1, 2, 3]=one to three, [7, 8, 9]=seven eat nine}