使用泛型创建集合对象

Tus*_*edi 11 java collections

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

Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Run Code Online (Sandbox Code Playgroud)

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

Rei*_*eus 20

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

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

虽然Map赋值的左外侧可以"变为"a HashMap分配,但同样不能应用于任何显示为通用参数的类型.

编辑:

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

Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Run Code Online (Sandbox Code Playgroud)

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

一些参考:

  • 你也可以使用`Map <Integer ,? extends Map <String,Integer >> myMap = new HashMap <Integer,HashMap <String,Integer >>();` (3认同)

Ami*_*itG 10

这是类似的错误

List<Animal> list = new ArrayList<Dog>();
Run Code Online (Sandbox Code Playgroud)

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

List<Animal> list = new ArrayList<Dog>(); // is not allowed
Run Code Online (Sandbox Code Playgroud)

Animal[] animal = new Dog[10];  //is allowed
animal[0] = new Dog(); // is allowed
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

List<Animal> list = new ArrayList<Animal>(); 
Run Code Online (Sandbox Code Playgroud)


Evg*_*eev 6

试试这个

Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Run Code Online (Sandbox Code Playgroud)

在一个更简单的例子上解释起来更容易

Set<Number> set = new HashSet<Integer>();
Run Code Online (Sandbox Code Playgroud)

是不允许的,因为那时你可以添加一个Double到整数的HashSet

set.add(1.0)
Run Code Online (Sandbox Code Playgroud)

注意

Set<? extends Number> set = new HashSet<Integer>();
Run Code Online (Sandbox Code Playgroud)

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

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