使用泛型创建集合对象

时间:2013-04-12 09:55:43

标签: collections java

当我尝试按如下方式创建对象时:

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();

语法上有什么问题,任何人都可以解释一下吗?

6 个答案:

答案 0 :(得分:20)

泛型不是共变体。您可以使用:

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
^                                                                ^
--------------^------------------- becomes ------^               |
              -----------------must remain as type ---------------

虽然作业左外侧的Map可以“成为”HashMap,但同样不能应用于任何显示为通用参数的类型。

编辑:

如@Keppil所述,您可以使用有界通配符语法:

Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();

请注意,此语法不允许将条目添加到地图中,但可用作要传递给方法和从方法传递的类型。

一些参考文献:

答案 1 :(得分:10)

类似的错误
List<Animal> list = new ArrayList<Dog>();

参数化类型的两端应该是相同的类型。没有继承(IS-A)概念。如果你仍然想使用它,那么使用带有extend / super关键字的通配符(?),只允许在等号的左侧。

List<Animal> list = new ArrayList<Dog>(); // is not allowed

Animal[] animal = new Dog[10];  //is allowed
animal[0] = new Dog(); // is allowed

如果有人试图添加Cat(扩展Animal)对象,它将在以后失败并抛出异常。

animal[1] = new Cat();  //compiles fine but throws java.lang.ArrayStoreException at Runtime.

请记住 animal[1] animal[index] 持有Dog reference。因此Dog引用变量可以引用Dog对象而不是Cat对象。

为了避免这种情况,JSL在泛型列表/集合中进行了这样的更改。此答案也适用于您的问题(Map)。
参数化类型在两端应该是相同的类型。

List<Animal> list = new ArrayList<Animal>(); 

答案 2 :(得分:6)

试试这个

Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();

在更简单的例子中解释更容易

Set<Number> set = new HashSet<Integer>();

是不允许的,因为那时你可以添加Double到HashSet of Integers

set.add(1.0)

请注意

Set<? extends Number> set = new HashSet<Integer>();

不允许在集合中添加除null之外的任何内容。但你只能从中读取数字

您可以在此处找到更多信息http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

答案 3 :(得分:3)

你需要这样的东西:

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
myMap.put(1, new HashMap<String, Integer>());

答案 4 :(得分:3)

Map<String, Integer>HashMap<String, Integer>不同。这就是问题所在。

实际上HashMap实现了Map接口。所以它应该在左侧? extends Map<String, Integer>

答案 5 :(得分:2)

试试这个:

Map<Integer, HashMap<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();