我有一个返回
实例的方法Map<String, List<Foo>> x();
和另一个返回
实例的方法Map<String, Collection<Foo>> y();
现在,如果我想在我的字段中动态添加其中一个地图,我该如何编写其中的泛型?
即:
public class Bar {
private Map<String, ? extends Collection<Foo>> myMap;
public void initializer() {
if(notImportant) myMap = x(); //OK
else myMap = y(); // !OK (Need cast to (Map<String, ? extends Collection<Foo>>)
}
}
即使将y()
声明为Collection,我也可以转换为签名吗?
如果不能投射,我可以以某种方式写这个(集合或列表) 我的意思是,List是一个集合,所以它应该是可能的。
private Map<String, Collection<Foo> | List<Foo>>> myMap;
答案 0 :(得分:4)
使用? extends Collection
执行此操作的方式很好。你不能拥有像OR这样的东西,因为如果你做了myMap.get("someString")
,你就不会知道你会得到什么。你不能做List|Collection someVariable = myMap.get("someString")
,你必须选择一个,如果你选择收藏它就像使用? extends
一样,如果你选择列表,你最终会遇到各种麻烦,如果map中的对象实际上是一个Set(也是一个集合),而不是一个列表,你尝试调用只有List的方法(比如indexOf)。至于您需要使用? extends
的原因是因为Map<String, List>
即使List扩展集合也不会扩展Map<String, Collection>
。
你应该注意,使用? extends Collection
只会让你从地图中获取值,从那以后它确定你得到的是一个Collection(或Collection的子),但如果你试图把在地图中的某些内容,您将无法(因为myMap可能是Map<String, Set>
,但由于您只将其视为Map<String, ? extends Collection>
,因此您可能会尝试在其中放置一个不合适的列表)
答案 1 :(得分:3)
我不确定你的问题是什么。这段代码(基本上是你的代码)编译得很好。
import java.util.*;
public class Generic {
static class Foo {};
static Map<String, List<Foo>> x() {
return null;
}
static Map<String, Collection<Foo>> y() {
return null;
}
static Map<String, ? extends Collection<Foo>> myMap;
public static void main(String[] args) {
myMap = x();
myMap = y();
myMap = new HashMap<String,SortedSet<Foo>>();
for (Collection<Foo> value : myMap.values());
}
}
但是,您不能执行List<Integer|String>
之类的操作。 Java泛型类型边界不起作用。