Java泛型和向上转换

Sim*_*mon 5 java generics type-conversion

有人可以解释一下为什么会这样

Map<String, List<String>> foo = new HashMap<String, LinkedList<String>>();
Run Code Online (Sandbox Code Playgroud)

生成类型不匹配错误?

类型不匹配:无法从HashMap <String,LinkedList <String >>转换为Iterators.Map <String,List <String >>

Hashmap实现Map接口,LinkedList实现List接口.而且,这个

List<String> foo = new LinkedList<String>();
Run Code Online (Sandbox Code Playgroud)

作品...

谢谢

Mar*_*ers 6

因为Map<String, List<String>>可以让你putArrayList<String>进入,但这样做会违反的类型完整性HashMap<String, LinkedList<String>>.

无论你声明HashMapHashMap<String, List<String>>或你作为一个变量Map<String, LinkedList<String>>Map<String, ? extends List<String>>.

编辑

更直接的问题是您导入了错误的Map类(被调用的东西Iterators.Map),或者您Map在与此代码相同的包中调用了另一个类(或内部类).你想导入java.util.Map.


Ale*_*exR 1

像下面这样修复这个问题:

Map<String, List<String>> result = new HashMap<String, List<String>>();

请注意我在你作业的右侧LinkedList更改了。List

你是对的,LinkedList 实现了 List。但我认为这个错误的解释不在 List 的定义中,而是在 interface 的定义中Map<K,V>

表达式的左侧表示您要创建字符串和列表的映射,即被V列表“替换”。右侧使用LinkedList。虽然LinkedList实现了List,但它不起作用,因为Map的定义不是类似的Map<K, V extends List>,所以编译器需要精确匹配。

我不确定我的描述是否足够严格,但无论如何,这是正确泛型的方法。实际上,当您创建列表的映射时,您并不关心列表的实现,因此可以说HashMap<String, List<String>>。只有当您创建 List 实例时才关心它的实现。这将允许您在将来更改实现而无需修改其他代码。