Java中的TypeMap

时间:2012-11-14 09:06:04

标签: java generics map

我想实现这样的地图,

Map<Class<T>, T> m;

其中,我可以得到类型为T的通用对象,给定T类。

我知道你可能会说,你可以包装一个Map<String, Object>并使用强制转换来存档它。

我知道这一点。

但是想象地图是Map<Class<T>, Collection<T>>,其中,值是一个非常大的集合。

我不想遍历集合并转换每个对象,因为集合太大了。

所以?我该怎么办?

3 个答案:

答案 0 :(得分:4)

Guava有类似的东西,称为ClassToInstanceMap

您可以详细了解in a dedicated Wiki section

但显然你需要的是ClassToInstanceMultimap。还没有,但您可以提交功能请求。

答案 1 :(得分:1)

  

我不想遍历集合并转换每个对象,因为集合太大了。

我不担心,因为

  • 你永远不需要这样做
  • 泛型是一个编译时检查,因此强制转换为泛型不会在运行时执行任何操作。

e.g。如果T extends Object,将Object转换为T则无效。类似地,将Collection转换为Collection<T>并不会在运行时执行任何操作。

  

但是想象一下,地图是Map&lt; Class&lt; T&gt;,Collection&lt; T&gt;&gt;,其中,该值是一个非常大的集合。

如果您认为这会做某事,那么施法就不是答案。您可能需要转换Collection的内容,但这在Java中完全不同。

答案 2 :(得分:0)

请注意,由于Java使用类型擦除,实现实际上将具有

的类型
Map<?, ?> = Map<Object, Object>

您可以轻松编写一个安全的访问方法,为您提供所需的类型安全性,例如:进行instanceOf检查:

public class InstanceMap extends HashMap<Class<?>, Object> {
    public <T> T getInstance(Class<T> cls) {
        Object o = super.get(cls);
        if (o != null && cls.isInstance(o)) {
            return (T) o;
        } else {
            return null;
        }
    }

    public <T> void putInstance(Class<T> cls, T value) {
        super.put(cls, value);
    }

    @Deprecated
    public Object get(Object key) {
        return super.get(key);
    }
}

除非您开始使用本身是通用的类型,否则这将正常工作。然后Class<? super T>会有所帮助。但总的来说,它主要给你一种错误的类型安全感。这种地图并没有为您提供您习惯的强大类型安全性。最后,它只不过是演员了。

我之前使用过这样的地图,但在使用它们1 - 2年后,我最终在清理阶段从我的代码中再次大大地消除了它们。他们是一个黑客,并没有像我预期的那样给予我多少好处。