2015-05-13 69 views
9

我想存儲一個基於由一組元素組成的鍵的值。就像下面的例子。當然,我知道我的僞示例不起作用,因爲對象的散列可能是它的地址,對於每個新實例而言,它是唯一的,而不管它的內容如何。如何在java地圖中使用一組元素作爲鍵?

// in this pseudo-example this is my SET http://algs4.cs.princeton.edu/35applications/SET.java.html 
    // but the idea is that values are unique 
    HashMap<SET<Integer>, String> map = new HashMap<>(); 
    SET a = new SET(); 
    a.add(1); 
    a.add(2); 
    a.add(5); 

    SET b = new SET(); 
    b.add(5); 
    b.add(1); 
    b.add(2); 

    map.put(a, "w00t"); 

    System.out.println(map.get(b)); // I would want to get "w00t" because my key is the same set of elements 

我當然只是排序並連接設置的值作爲一個字符串,用分離器,並使用在HashMap<String, String>結構,但只是感覺不對。我對Java編程頗爲陌生,所以可能有一個明顯的解決方案,我錯過了。

+0

你必須看看'keySet()'。此外,它是一個'集'而不是'SET' –

+0

我認爲如果你想爲這個工作使用集合,這裏有一個大問題。他們都是可變的。如果添加集合(2,3)和(1,2,3),但是您決定從第二集合中刪除{1}會怎樣?更好地爲此創建一個單獨的不可變對象,否則會令人煩惱。 – pnadczuk

+0

我意識到這一點,但在我的情況下,我不會修改對象,一旦我存儲它們。理想情況下,我想有一個不可變的對象,我從其他迭代初始化,但沒有一個,我可以找到:( – ddinchev

回答

7

如果使用,而不是您的自定義設置(我假設它是一個自定義類),它會工作得很好,因爲HashSet覆蓋hashCodeequals(準確的說,HashSet延伸AbstractSet將覆蓋這些方法)所以它可以作爲HashMap中的關鍵。

但是,如果修改作爲Map中的鍵的Set,那麼您將無法在稍後的Map中找到該鍵。在使用可變對象作爲HashMap中的鍵時,這是您遇到的風險。

HashMap<HashSet<Integer>, String> map = new HashMap<HashSet<Integer>, String>(); 
HashSet<Integer> a = new HashSet<Integer>(); 
a.add(1); 
a.add(2); 
a.add(5); 

HashSet<Integer> b = new HashSet<Integer>(); 
b.add(5); 
b.add(1); 
b.add(2); 

map.put(a, "w00t"); 

System.out.println(map.get(b)); 

此輸出w00t

+0

我看着它。它不覆蓋,它只是繼承。 – ddinchev

+1

@ddinchev它工作正常。試試吧,看看你自己。 – gdejohn

+2

@ddinchev是的,我是不準確的,AbstractSet重寫。 – Eran

0

創建一個集合類並重寫hashcode(),其中對於具有相同內容的不同集合實例返回相同的哈希碼。您可以簡單地重寫派生自所需集合的類中的方法。你也必須重新實現equals(Object o)。

+0

JDK集合實現已經爲你做了。 – gdejohn

+0

如何使用不同比較器的兩個OrderedSet實例? – Traubenfuchs

+0

仍然有效。如果你查看['TreeSet']的文檔(https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html),你可以看到它繼承了它的['equals( )'](https://docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html#equals-java.lang.Object-)和['hashCode()'](https:從'AbstractSet'實現的.docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html#hashCode--)實現。 「Set接口將所有構造函數的合約以及add,equals和hashCode方法的契約之外的其他約束放在除Collection接口繼承的那些約束之外。」 – gdejohn

-2

您沒有將集b添加到您的地圖。首先添加兩組,然後嘗試獲取與密鑰b相關聯的值。

+2

這就是OP的要點 - 兩組都具有相同的元素,並且應該相同,但添加了「a」的對象作爲密鑰不能使用「b」進行檢索。發生這種情況是因爲他沒有在自定義集合實現中重寫'hashCode'或'equals'。 –

-1

這取決於你的SET類的實現。您可以在您的SET類中擴展java.util.HashSet類或實施equals()hashCode()方法。任何解決方案都可以。

相關問題