通用工厂和地图价值

时间:2009-09-21 18:31:43

标签: java generics map arguments factory

对于几个不同的Map,我有KSet<V> s V的课程。我想使用通用工厂ala:

protected static <T> Set<T> SetFactory(int size) {
        return new HashSet<T>(size);
}

做类似

的事情
for (K key : keySet) map.put(key, SetFactory());

并使通用部分工作(我收到编译错误,Set<Object>Set<V>之间的类型不匹配),就像Set<V> x = SetFactory();

一样

是否有将Class<V>参数传递给SetFactory()的替代方法?

5 个答案:

答案 0 :(得分:2)

我真的不明白你的问题。这是你在找什么?

class MyClass {

  protected static <T> Set<T> SetFactory(int size)
  {
    return new HashSet<T>(size);
  }

  protected static <K, V> Map<K, Set<V>> mapFactory(Collection<K> keys)
  {
    Map<K, Set<V>> result = new HashMap<K, Set<V>>(keys.size());
    for (K key : keys)
      result.put(key, MyClass.<V>SetFactory(20));
    return result;
  }

}

请注意泛型方法调用的显式类型参数(<V>)。


更新

  

我可能错了,但在那里说   没有演员对我来说似乎是语义    - 不得不把MyClass。在前面似乎非常接近必须   投。你能解释一下这个区别吗?

强制转换为(Set<V>) SetFactory(20),它会生成有关类型安全性的编译器警告,因为对于类型擦除,无法检查SetFactory的结果的运行时类型函数的类型为V

在方法调用上使用类型参数很像说new HashSet<V>()。调用泛型类的构造函数时,必须指定构造函数的类型参数。无论何时调用泛型方法,都必须指定类型参数。通常,这些可以从方法结果的赋值或方法的参数中推断出来,但并非总是如此。

但是,它不是演员。强制转换总是在运行时执行类型检查。我在此处显示的指定泛型类型在编译时工作。

答案 1 :(得分:0)

您需要明确的作业:

for (K key : keySet) {
  Set<V> mySet = setFactory(20);
  map.put(key, mySet);
}

没有它,编译器就无法知道<V>

的类型

答案 2 :(得分:0)

Apache Commons Collections提供LazyMap,您可以在其中提供Factory对象,该对象可创建地图的值。您可以提供一个创建Set值的Factory。

现在,Commons Collections不使用泛型,但它有一个通用端口here

我希望我能正确地解释你的问题 - 这很令人困惑。

答案 3 :(得分:0)

如果你绝对必须在一条线上,你可以在看跌期权中加入一个胡扯:

 Set<V> s = null;
 for (K key : keySet) map.put(key, s = setFactory());

但是,答案更多的是表明另一种方法,而不是实际上建议这是一种更好的方式。

答案 4 :(得分:0)

嗯,实际上这似乎有效:

protected static <K,V> Map<K,Set<V>> mapFactory(Collection<K> keys) {
    Set<V> holder;
    Map<K,Set<V>> result = new HashMap<K,Set<V>>(keys.size());
    for (K key : keys) result.put(key, holder = SetFactory());
    return result;
}

甚至让我摆脱了最初分配地图的烦恼。我想我需要在参数列表中添加一个工厂,如果我想实际上能够覆盖该类。