2012-10-24 76 views
3

我想什麼有是這樣的值的列表:Java的地圖,其中的值是相同類型的關鍵

public abstract Class Content { 
    private Map<Class<? extends Content>, List<? extends Content>> relations; 
} 

內容有子類的一堆 - A,B,C ,d等..

最常見的用例是獲得全A:

public List<A> getA() { 
    return (List<A>)relations.get(A.class); 
} 

確定的種類 - 除了難看的演員。

但真正的問題是沒有什麼東西做這樣愚蠢的東西阻止我:

relations.put(A.class, List<B> myListOfBs); 
以上

所以要木屐()的調用將導致可怕的轉換異常。有什麼辦法可以編寫它,所以編譯器會在上面的例子中提醒我 - 也刪除了對醜陋演員的需求。

感謝

回答

3

您可以創建一個圍繞Map的包裝,並使用一個通用的方法來約束你的put方法:

public class HeterogeneousContainer { 
    private final Map<Class<? extends Content>, List<? extends Content>> map; 

    public <T extends Content> void put(Class<T> type, List<T> values) { 
     map.put(type, values); 
    } 


    public <T extends Content> List<T> get(Class<T> type) { 
     //this warning can be safely suppressed after inspection 
     return (List<T>) map.get(type); 
    } 
} 

現在你知道,只要容器的用戶不如果使用不當(即以原始形式),那麼密鑰和數值必須一致......您不能撥打put(B.class, listOfAs);

+0

一個很好的答案 - 謝謝 – user617136

0

創建一個自定義Map接口,修復類型的相同類型:

interface RelatedMap<T> extends Map<Class<T>, List<T>> {} 

然後

private RelatedMap<? extends Content> relations; 
+0

這似乎是一個很酷的想法,但沒有按實際上並非如此。您無法將任何內容添加到「關係」中,因爲Java無法處理捕獲問題。例如。你不能做'RelatedMap <?擴展CharSequence>關係; relations.put(String.class,new ArrayList ());'。 –

+0

此外,它不能工作,因爲它會是不安全的類型:'RelatedMap strings;相關地圖 anything = strings; anything.put(Integer.class,Arrays.asList(1,2)); String str = strings.values()。iterator()。next()。get(0);'< - 類型錯誤 –

+0

@Bohemian ..... – jahroy

相關問題