2010-06-02 97 views
2

我有一个返回的在Java泛型声明中使用“或”

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 OR List) 我的意思是,List是一个集合,所以它应该以某种方式成为可能。

private Map<String, Collection<Foo> | List<Foo>>> myMap; 

回答

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泛型类型边界就不能像那样工作。

+0

也编译得很好'javac 1.6.0_17'。正如它应该。 – polygenelubricants 2010-06-02 16:10:37

4

你用? extends Collection这样做的方式很好。你不能拥有像OR这样的东西,因为如果你这样做了,你不会知道它是什么,如果你做myMap.get("someString");你不能做List|Collection someVariable = myMap.get("someString"),你必须选择一个,如果你选择Collection,它与使用? extends相同,如果你选择List,如果地图中的对象实际上是一个Set,那么最终会遇到各种麻烦(这也是一个集合),而不是一个列表,你尝试调用只有List的方法(如indexOf)。至于你需要使用? extends的原因是因为Map<String, List>不延伸Map<String, Collection>即使列表扩展集合。

你应该注意到虽然,使用? extends Collection只会让你从地图中获取值,因为那就是确保你得到的是一个集合(或收藏的孩子),但如果你试图把东西在地图,你将无法(因为我的地图可能是Map<String, Set>,但因为你只看到它作为Map<String, ? extends Collection>你可能会尝试把一个列表中,这将是不好的)

+0

+1;另见http://stackoverflow.com/questions/2776975/how-can-i-add-to-list-extends-number-data-structures – polygenelubricants 2010-06-02 16:19:21