DlaczegoJak korzystać z addAll przy użyciu ogólnej kolekcji?
List<Map<String, Object>> a, b;
a.addAll(b);
skompilować
Ale
List<? extends Map<String, ?>> a, b;
a.addAll(b);
nie.
Jak wykonać tę ostatnią kompilację?
DlaczegoJak korzystać z addAll przy użyciu ogólnej kolekcji?
List<Map<String, Object>> a, b;
a.addAll(b);
skompilować
Ale
List<? extends Map<String, ?>> a, b;
a.addAll(b);
nie.
Jak wykonać tę ostatnią kompilację?
Nie można dodawać pozycji do ogólnej listy symboli wieloznacznych. Pierwszy kompiluje się, ponieważ ma określony typ.
Możesz jednak znaleźć super klasę, która pasuje do twojego celu i użyć go jako ogólnego argumentu.
UPDATE:
zobaczyć również Wildcard (in the Oracle docs)
Dlaczego ta kompilacja również nie działa? 'Lista extends Map
To znowu, ponieważ dodajesz elementy do swojej generycznej kolekcji symboli wieloznacznych. a'. – DerMike
Ponieważ próbujesz dodać w kolekcji zdefiniowanej za pomocą symboli wieloznacznych i to nie jest dozwolone w Javie. – arjacsoh
Kiedy deklarujesz ją z betonu ogólny typ, kompiluje. Jeśli zdefiniujesz klasę:
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;
}
}
Z symbolami wieloznacznymi, których nie można skompilować.
Według java docs można zadeklarować metody pomocnika w tym przypadku (brzydki, ale działa):
static <T extends List<K>, V, K extends Map<String, V>> void addAllHelper(T from, T to) {
from.addAll(to);
}
Można to zrobić za pomocą metody jak:
private <S extends Map<String, ?>> void method(List<S> a, List<S> b){
a.addAll(b);
}
Wyobraźmy sobie, że CustomHashMap
rozciąga HashMap
i zainicjować a
jak poniżej:
List<CustomHashMap<String, String> list = new ArrayList<CustomHashMap<String, String>>();
List<? extends Map<String, ?>> a = list;
jeśli byli w stanie dodać wpisy do a
...
a.add(new HashMap<String, String>());
... będzie można spotkać tę dziwną sytuację
CustomHashMap<String, String> map = list.get(0); // you would expect to get CustomHashMap object but you will get a HashMap object instead
Innymi słowy, nie wiem, co do rzeczywistego typu z twojej mapy (kiedy mówisz? extends Map), wszystko co wiesz to to, że jest to podtyp mapy i nie możesz dodawać dowolnych obiektów do Listy, ponieważ musisz upewnić się, że istnieje supertyp dla dodanego obiektu. Ale nie możesz, ponieważ dokładny typ mapy jest nieznany.
poniższy kod powinien pomóc wyjaśnić ten
List<? super Number>
się nazywa out
parametru i mogą być wykorzystane do aktualizacji List<? extends Number> b
nazywa in
parametru i może być używany do odczytu
skomentowane linie poniżej powoduje błąd kompilacji z powodów wymienionych w komentarzach
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);
}
Wymiana '?extends Map 'dla typu, który rozszerza' Map 'ponieważ deklarując zmienne musisz podać im typ. Jeśli nie, musisz użyć interfejsów jak w pierwszym przykładzie. –
LuigiEdlCarno