如何在里面创建一个复杂结构的列表

时间:2012-02-14 09:34:34

标签: java generics

我有以下两个类:

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表达它?

4 个答案:

答案 0 :(得分:3)

使用

? extends
地图声明中的

答案 1 :(得分:1)

没有办法做到这一点。这里的问题是您希望键类型的地图值类型依赖。在这里使用泛型实际上不是问题。例如,无法声明映射具有始终与整数值关联的整数键和与字符串值关联的字符串键。您将始终必须键入键和值作为常用超类型(可能是对象)并转换为期望的类型。

答案 2 :(得分: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);
  }
}

然而,这是一种黑客行为。有谁知道更好的答案?

答案 3 :(得分:-1)

您可以按以下方式分配地图

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