java Java泛型放在 Map<String, ? 扩展列表<字符串>>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/871521/
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
Java Generics putting on Map<String, ? extends List<String>>
提问by Michael Myers
Is there a way to make the following implementation in a type safe manner?
有没有办法以类型安全的方式进行以下实现?
public void myMethod( Map<String, ? extends List<String>> map )
{
map.put("foo", Collections.singletonList("bar");
}
The above implementation doesn't work. It requires a Map<String, ? super List<String>>to compile the method map.put()correctly. But myMethod won't accept any subtype of List this way. So, I have to use Map<String, ? extends List<String>>instead. How can I solve this problem in a type safe manner?
上面的实现不起作用。它需要 aMap<String, ? super List<String>>才能map.put()正确编译该方法。但是 myMethod 不会以这种方式接受 List 的任何子类型。所以,我必须Map<String, ? extends List<String>>改用。如何以类型安全的方式解决此问题?
回答by KitsuneYMG
public void myMethod( Map<String, List<String>> map ) {
map.put("foo", Collections.singletonList("bar") );
}
You can't put a List(the return type of Collections.singletonList()into a Mapof ? extends Listsince the actual type could be any implementation of List. For example, it is notsafe to put a generic Listinto a Map<String,LinkedList>since the Listmight not be a LinkedList. However, we can easily put a LinkedListinto a Mapof <String,List>.
你不能把一个List的(返回类型Collections.singletonList()到Map的? extends List,因为实际的类型可能是任何实现List。例如,它是不是安全的把一个普通的List成Map<String,LinkedList>因为List可能不是LinkedList。不过,我们可以很容易地把aLinkedList变成 aMap的<String,List>。
I think you were over thinking your generics. You do not have to use ? extendsfor a non-generic class. For example, List<Object>will hold any Object, the ? extendsis not needed to add an object. A List<List<Foo>>will only take List<Foo>objects and not List<FooSubclass>objects [Generic classes don't inherit based on their parameters]. This is where ? extendscomes into play. To add both List<Foo>and List<FooSubclass>to a List, the type must be List<List<? extends Foo>>.
我认为你是在考虑你的泛型。您不必? extends用于非泛型类。例如,List<Object>将持有 any Object,? extends不需要添加对象。AList<List<Foo>>只会接受List<Foo>对象而不是List<FooSubclass>对象[通用类不会根据它们的参数继承]。这就是? extends发挥作用的地方。要将List<Foo>和添加List<FooSubclass>到 a List,类型必须是List<List<? extends Foo>>。
回答by Michael Myers
Wouldn't Map<String, List<String>work? Is there some particular reason you have to have a wildcard there at all?
会不会Map<String, List<String>工作?有什么特别的原因你必须在那里有一个通配符吗?
回答by Michael Myers
There is a very simple principle when using Collections and Generics together. It is called "The Get and The Put Principle":
集合和泛型一起使用时有一个非常简单的原则。它被称为“获取和放置原则”:
Use an "extends" wildcard when you only GET values out of a collection, use "super" wildcard when you only PUT values into a collection and don't use any wildcard when you want both get and put.
当您只从集合中获取值时使用“扩展”通配符,当您只将值放入集合时使用“超级”通配符,并且当您想要获取和放置时不要使用任何通配符。
So, as you can see, the initial example is invalid, according to this principle.
所以,正如你所看到的,根据这个原则,最初的例子是无效的。
回答by Laurence Gonsalves
Imagine if someone passed you a Map<String, ArrayList<String>>. The value you're putting in is the result of Collections.singletonList which is notan ArrayList.
想象一下,如果有人给你传了一个Map<String, ArrayList<String>>. 你投入的价值是Collections.singletonList的结果,这是不是一个ArrayList。
You cannot accept any subtype of List in the Map and then expect to be able to add your own, possibly incompatible, subtype.
您不能在 Map 中接受 List 的任何子类型,然后期望能够添加您自己的,可能不兼容的子类型。

