2012-02-14 67 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); 
    } 
} 

但是这有点本事。有谁知道更好的答案?

相关问题