将子类型的HashMap转换为超类型的HashMap

时间:2012-08-14 13:13:41

标签: java generics casting hashmap

我确实遇到了操纵哈希映射的麻烦。我的问题很简单,但我不能让它发挥作用......

我有一个名为MultilineWritable的界面。我需要在平面文件上编组的类确实实现了这个接口,它定义了String toFlatFormat()函数及其相对的init(String flatFormat)

现在假设Contract类实现MultilineWritable并且由整数标识,而Person类也实现此接口但由字符串标识。

我对合同和人员的HashMaps进行编组的功能如下:

public void marshall(HashMap<Object, MultilineWritable>){}

我的问题是我无法找到将HashMap<String, Person>投射到HashMap<Object, MultilineWritable>的方法,即使String延伸ObjectPerson延伸{{1} }}。对于MultilineWritable的投射也是如此...因此我无法调用我的通用函数。

关于此问题的任何帮助。

3 个答案:

答案 0 :(得分:5)

假设您的marshall方法只有读取值,您只需将声明更改为:

public void marshall(HashMap<?, ? extends MultilineWritable> map)

问题在于,如果允许现有的方法调用,它可能会尝试将任何 MultilineWritable放入地图中 - 即使它是错误的地图类型:

Map<String, Person> map = new HashMap<String, Person>();

// What would you want map.put("foo", new Contact()) to do inside marshall?
marshall(map);

编辑:有关通配符的更多详细信息,请参阅Java Generics FAQ

答案 1 :(得分:0)

您要做的是将specific type传递给generic type。您需要使用java的generics功能。泛型提供compile time safety only,因此当您被允许将特定类型传递到采用遗传类型的函数时,您不能修改集合或映射。

简而言之,你的anser是:

public void marshall(HashMap<? extends Object, ? extends MultilineWritable> map)

答案 2 :(得分:0)

在Java Generics中not Covariant。所以你不能做以下

    List<Integer> numList = new ArrayList<Integer>();
    List<Number> numList = new ArrayList<Number>();
    numList = numList; //Error
    numList = (List<Number>)intList; //error

编译器使用泛型来典型安全。实际的类型信息(集合的信息,即这是整数列表)等在运行时丢失。