我需要使用带有List的Map:
Map<String, List<String>> keyToGroup = new HashMap<String, ArrayList<String>>();
我在eclipse中遇到编译错误。
唯一可行的工作似乎是将Map中的内部List更改为ArrayList
Map<String, ArrayList<String>> keyToGroup = new HashMap<String, ArrayList<String>>();
我不得不改变许多接口方法的签名,但我仍然没有得到它;为什么第一个定义不起作用?
是不是一样,不应该
Map<String, List<String>> keyToGroup
&安培;
Map<String, ArrayList<String>>
是一样的吗?
答案 0 :(得分:8)
不,他们不是。考虑一下:
Map<String, List<String>> keyToGroup = new HashMap<String, ArrayList<String>>();
keyToGroup.put("foo", new LinkedList<String>());
第二行没问题,因为LinkedList<String>
是List<String>
- 但在将HashMap<String, ArrayList<String>>
添加到LinkedList<String>
方面,它在逻辑上并不合适,因为ArrayList<String>
是不 Map<String, ArrayList<String>> map1 = new HashMap<String, ArrayList<String>>();
Map<String, List<String>> map2 = map1; // This is invalid
map2.put("foo", new LinkedList<String>());
ArrayList<String> oops = map1.get("foo"); // Because this would be broken
。
更清楚:
List<Banana> bunchOfBananas = new ArrayList<Banana>();
List<Fruit> fruitBowl = bunchOfBananas; // Invalid!
fruitBowl.add(new Apple());
Banana banana = bunchOfBananas.get(0);
这不仅仅是集合作为类型参数的情况。使用正常继承看起来更简单:
{{1}}
即使每个香蕉都是水果,所以“香蕉的集合”是“收集水果*”,意思是取出它们,而不是每种香蕉都是香蕉。
在某些情况下,您可以使用wildcard parameterized types来提供帮助,但这取决于您要实现的目标。
答案 1 :(得分:0)
不,他们不是。泛型在Java中不是协变。
如果它们是协变的,你可以在逻辑上放置任何类型的List
而不是ArrayList
,这会违背仿制药的目的。
考虑阅读Effective Java(第2版)第5章:泛型,它对泛型有非常好的解释。
另一个好的读物是http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
答案 2 :(得分:0)
如果您需要在地图或任何列表中使用特定列表,请问自己一个问题? 如果是特定实现,您可以使用上一个示例:
Map<String, ArrayList<String>> keyToGroup = new HashMap<String, ArrayList<String>>();
如果有任何列表,请使用:
Map<String, List<String>> keyToGroup = new HashMap<String, List<String>>();
keyToGroup.put("arraylist", new ArrayList<String());
keyToGroup.put("linkedlist", new LinkedList<String());
BTW第二个选项通常从设计的角度来看更好,所以如果你现在还不知道 - 请先尝试使用第二个选项。