Java 初始化带有列表的地图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18887598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:55:42  来源:igfitidea点击:

Initializing a Map with List inside

java

提问by TheO

I need to use a Map with a List inside :

我需要使用带有列表的 Map :

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

I am getting compiler error on this line in eclipse.

我在 eclipse 中的这一行出现编译器错误。

The only working thing seem to be changing the inside List in the Map to ArrayList

唯一的工作似乎是将 Map 中的内部 List 更改为 ArrayList

Map<String, ArrayList<String>> keyToGroup = new HashMap<String, ArrayList<String>>();

I had to change the signature of many interfaces' methods, but I still don't get it; why isn't the first definition work?

我不得不更改许多接口方法的签名,但我仍然不明白;为什么第一个定义不起作用?

Isn't it the same, should not

是不是一样,不应该

Map<String, List<String>> keyToGroup 

&

&

Map<String, ArrayList<String>>

be the same?

是相同的?

采纳答案by Jon Skeet

No, they're not. Consider this:

不,他们不是。考虑一下:

Map<String, List<String>> keyToGroup = new HashMap<String, ArrayList<String>>();
keyToGroup.put("foo", new LinkedList<String>());

The second line is fine, because a LinkedList<String>is a List<String>- but it's not logically fine in terms of adding it to a HashMap<String, ArrayList<String>>, because a LinkedList<String>is notan ArrayList<String>.

第二行是好的,因为LinkedList<String>List<String>-但它不是逻辑罚款,将其添加到一个方面HashMap<String, ArrayList<String>>,因为LinkedList<String>没有ArrayList<String>

To make it clearer:

为了更清楚:

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

This isn't just the case with collections as the type argument. It's even simpler to see with normal inheritance:

这不仅仅是将集合作为类型参数的情况。使用普通继承更简单:

List<Banana> bunchOfBananas = new ArrayList<Banana>();
List<Fruit> fruitBowl = bunchOfBananas; // Invalid!
fruitBowl.add(new Apple());
Banana banana = bunchOfBananas.get(0);

Even though every banana is a fruit, so a "collection of bananas" is a "collection of fruit* in the sense of fetchingthem, not every fruit is a banana.

即使每个香蕉都是水果,因此“香蕉的集合”是“水果集合*”,但在获取它们的意义上,并非每个水果都是香蕉。

You can use wildcard parameterized typesto help in some cases, but it depends on exactly what you're trying to achieve.

在某些情况下,您可以使用通配符参数化类型来提供帮助,但这完全取决于您要实现的目标。

回答by Jaydeep Patel

No they are not. Generics are not covariantin Java.

不,他们不是。Java 中的泛型不是协变的。

If they are covariant you can logically put any type of Listinstead of ArrayListwhich defeats the purpose of having generics.

如果它们是协变的,您可以在逻辑上放置任何类型的List而不是ArrayList哪个会破坏拥有泛型的目的。

Consider reading Effective Java (2nd Edition) Chapter 5: Generics which has very good explanation of Generics.

考虑阅读 Effective Java(第 2 版)第 5 章:泛型,它对泛型有很好的解释。

Another good read is http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

另一个不错的读物是http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

回答by Sergey F

Ask yourself a question if you need particular list implementation in your Map or any List? In case of particular implementation you can use your last example:

问自己一个问题,如果您需要在您的地图或任何列表中实现特定的列表?在特定实现的情况下,您可以使用最后一个示例:

Map<String, ArrayList<String>> keyToGroup = new HashMap<String, ArrayList<String>>();

In case of any list just use:

如果有任何列表,只需使用:

Map<String, List<String>> keyToGroup = new HashMap<String, List<String>>();
keyToGroup.put("arraylist", new ArrayList<String());
keyToGroup.put("linkedlist", new LinkedList<String());

BTW the second option usually is better from design point of view so if you don't know exactly for now - try using second option first.

顺便说一句,从设计的角度来看,第二个选项通常更好,所以如果你现在不完全知道 - 首先尝试使用第二个选项。