2010-06-02 96 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