2012-02-14 29 views
2

複雜結構的名單上有以下兩類:如何創建裏面

class Key<T1, T2> {} 
class Pair<F, S> {} 

我想創建一個映射,從Key<T1, T2>List<Pair<T1, T2>>其中T1和T2是每個地圖的入口不同。我想實現這樣說:

class KeyToListMap { 
    private Map<Key<?, ?>, List<Pair<?, ?>>> myItems = new HashMap<Key<?, ?>, List<Pair<?, ?>>>(); 


    public<T1, T2> List<Pair<T1, T2>> getList(Key<T1, T2> key) { 
    if (!myItems.containsKey(key)) { 
     myItems.put(key, new ArrayList<Pair<T1, T2>>()); 
    } 
    return (List<Pair<T1, T2>>) myItems.get(key); 
    } 
} 

但是我有兩個類型的錯誤:

put(test.Key<?,?>,java.util.List<test.Pair<?,?>>) in java.util.Map<test.Key<?,?>,java.util.List<test.Pair<?,?>>> cannot be applied to (test.Key<T1,T2>,java.util.ArrayList<test.Pair<T1,T2>>) 

inconvertible types 
found : java.util.List<test.Pair<?,?>> 
required: java.util.List<test.Pair<T1,T2>> 

我怎樣才能表達這種在Java中,而不訴諸使用原始類型?

+0

''是*未知類型*,該類型與其他類型不同。這就是爲什麼這些類型不可轉換的原因。這是一個常見的誤解,認爲'?'是任何類型的佔位符 – 2012-02-14 09:46:47

+0

2Andreas_d。我明白。但我怎麼能表達我想要的? – 2012-02-14 09:48:58

+0

順便說一句:你聽說過KISS原則嗎?沒有冒犯,但是在你完成代碼的一年後,你能夠(期望別人能夠)真正理解這裏發生的事情嗎? – aviad 2012-02-14 10:40:43

回答

3

使用

? extends 

在地圖聲明

+0

我應該在哪裏做? – 2012-02-14 10:02:24

+0

在「地圖聲明」(如我所述)。私人地圖,列表<? extends Pair >> myItems .... 是未知類型,因此您需要提供某種抽象類或甚至Marker接口來指示編譯器期望什麼。 – aviad 2012-02-14 10:28:20

+0

我自己也使用了相同的解決方案(請參見下文),但看起來相當拙劣。 Pair沒有任何子類型,這樣做沒有意義。 – 2012-02-14 12:34:17

-1

您可以在地圖分配如下

private Map<Key<T1, T2>, List<Pair<F, S>>> myItems = new HashMap<Key<T1, T2>, List<Pair<F, S>>>(); 
+0

我不能T1和T2是方法的類型參數,而不是類的參數。 – 2012-02-14 09:45:33

+0

我以爲T1和T2真的是class。如果不是,試試'?擴展T1'而不是 – plucury 2012-02-15 04:38:31

1

有沒有辦法做到這一點。這裏的問題在於,您希望映射值類型取決於密鑰類型上的。這裏泛型的使用其實不是問題。例如,無法聲明映射具有總是與整數值和與字符串值關聯的字符串鍵相關聯的整數鍵。您將始終必須鍵入鍵和值作爲一個常見的超類型(可能是對象),並轉換爲預期的類型。

+0

那麼你可以舉一個例子來說明我應該如何重寫上面的代碼來編寫代碼? – 2012-02-14 09:53:34

0

我實現這樣的:

class Key<T1, T2> { 
} 

class Pair<F, S> { 

} 

class KeyToListMap { 
    private Map<Key<?, ?>, List<? extends Pair<?, ?>>> myItems = new HashMap<Key<?, ?>, List<? extends Pair<?, ?>>>(); 

    public<T1, T2> List<Pair<T1, T2>> getList(Key<T1, T2> key) { 
    if (!myItems.containsKey(key)) { 
     myItems.put(key, new ArrayList<Pair<T1, T2>>()); 
    } 
    return (List<Pair<T1, T2>>) myItems.get(key); 
    } 
} 

但是這有點本事。有誰知道更好的答案?