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