繁体   English   中英

Java泛型放在地图上 <String, ? extends List<String> &gt;

[英]Java Generics putting on Map<String, ? extends List<String>>

有没有办法以类型安全的方式进行以下实现?

public void myMethod( Map<String, ? extends List<String>> map )
{
   map.put("foo", Collections.singletonList("bar");
}

上述实现不起作用。 它需要Map<String, ? super List<String>> Map<String, ? super List<String>>正确编译方法map.put() 但myMethod不会以这种方式接受List的任何子类型。 所以,我必须使用Map<String, ? extends List<String>> Map<String, ? extends List<String>> 如何以类型安全的方式解决此问题?

public void myMethod( Map<String, List<String>> map ) {
    map.put("foo", Collections.singletonList("bar") );
}

你不能把一个List (返回类型的Collections.singletonList()Map? extends List ,因为实际的类型可能是任何实现List 。例如,它是不是安全的把一个普通的ListMap<String,LinkedList>因为List可能不是LinkedList 。但是,我们可以轻松地将LinkedList放入<String,List>Map中。

我想你已经在考虑你的仿制药了。 你不必使用? extends ? extends为非泛型类。 例如, List<Object>将持有的任何Object ,则? extends 不需要? extends来添加对象。 List<List<Foo>>只接受List<Foo>对象而不是List<FooSubclass>对象[通用类不会根据它们的参数继承]。 这是哪里? extends ? extends发挥作用。 要将List<Foo>List<FooSubclass>List ,类型必须是List<List<? extends Foo>> List<List<? extends Foo>>

Map<String, List<String>不会工作吗? 有什么特别的原因你必须在那里有一个通配符吗?

将Collections和Generics一起使用时,有一个非常简单的原则。 它被称为“获取和放置原则”:

当你只从集合中获取值时使用“扩展”通配符,当你只将PUT值放入集合时使用“超级”通配符,当你想要get和put时不使用任何通配符。

所以,正如你所看到的,根据这个原则,最初的例子是无效的。

想象一下,如果有人传给你一个Map<String, ArrayList<String>> 您输入的值是Collections.singletonList的结果,它不是 ArrayList

您不能接受Map中任何List的子类型,然后期望能够添加您自己的,可能不兼容的子类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM