2013-08-30 45 views
5

爲什麼如何在泛型集合中使用addAll?

List<Map<String, Object>> a, b; 
a.addAll(b); 

編譯

List<? extends Map<String, ?>> a, b; 
a.addAll(b); 

沒有。

如何讓後者編譯?

+0

交換?擴展Map '爲擴展'Map '的類型,因爲在聲明變量時需要給它們一個類型。如果不是,則需要像第一個示例中那樣使用接口。 – LuigiEdlCarno

回答

2

您無法將項目添加到通配符通用列表。第一個編譯是因爲它有一個定義的類型。

但是,您可能會發現一些適合您的目的的超類,並將其用作一般參數。

UPDATE:

也看到Wildcard (in the Oracle docs)

+0

爲什麼不編譯? 'List <?擴展地圖> a;' 'List > b;' 'a.addAll(b);' – Pinch

+1

這又是因爲您要將項目添加到通配符泛型集合'了'。 – DerMike

+0

因爲您嘗試添加用通配符定義的集合,並且這在Java中是不允許的。 – arjacsoh

0

當你用混凝土泛型類型聲明它,它編譯。如果您定義了一個類:

public class AClass<T extends Map<String, ?>> { 

    public List<T> dostuff() { 

     List<T> lista = new ArrayList<T>(); 
     List<T> listb = new ArrayList<T>(); 

     lista.addAll(listb); 
     return lista; 
    } 
} 

使用通配符無法編譯。

1

根據java docs你可以在這種情況下宣佈的輔助方法(醜,但工程):

static <T extends List<K>, V, K extends Map<String, V>> void addAllHelper(T from, T to) { 
     from.addAll(to); 
} 
0

可以使用的方法一樣做到這一點:

private <S extends Map<String, ?>> void method(List<S> a, List<S> b){ 
    a.addAll(b); 
} 
2

試想一下,CustomHashMap延伸HashMap和你初始化a如下:

List<CustomHashMap<String, String> list = new ArrayList<CustomHashMap<String, String>>(); 
List<? extends Map<String, ?>> a = list; 

,如果你能夠將條目添加到a ...

a.add(new HashMap<String, String>()); 

...你會遇到這種奇怪的情況

CustomHashMap<String, String> map = list.get(0); // you would expect to get CustomHashMap object but you will get a HashMap object instead 

換句話說,你不知道實際的類型你的地圖(當你說?擴展Map),所有你知道的是它是Map的一個子類型,你不能向List中添加任意對象,因爲你需要確保添加的對象有一個超類型。但由於地圖的確切類型未知,因此無法進行。

0

下面的代碼應該幫你解釋這個

List<? super Number>被稱爲out參數,可用於更新 List<? extends Number> b被稱爲in參數,可以用來讀取

下面的編譯錯誤結果

註釋行因爲在評論中提到的原因

public static void main(String[] args) { 
    List<Integer> intList = new ArrayList<>(); 
    List<Double> doubleList = new ArrayList<>(); 
    List<Number> numberList = new ArrayList<>(); 
    addAll(numberList, intList); 
    addAll(numberList, doubleList); 
    addAll(intList, doubleList);//cant add double to int 
    addAll(doubleList,intList);//cant add int double 
    addAll(intList, numberList);//cant add number to int 
} 

private static<T> void addAll(List<? super T> a, List<? extends T> b) { 
    a.addAll(b); 
}