Zróbmy przykład, aby było łatwiej. Buduję listę, którą konstruktor pobiera integer
i List<Integer>
. Moja lista zawiera wszystkie elementy z podanej listy pomnożone przez integer
. Moja lista nie przechowuje nowe elementy, ale obliczyć je na bieżąco:Jak zwrócić obiekt z wieloma typami?
class MyList extends AbstractList<Integer> implements RandomAccess {
private final int multiplier;
private final List<Integer> list;
public MyList(int multiplier, List<Integer> list) {
this.multiplier = multiplier;
this.list = list;
}
@Override
public Integer get(int index) {
return list.get(index) * multiplier;
}
@Override
public int size() {
return list.size();
}
}
Wtedy możemy nazwać new MyList(3, list)
z list = [0, 1, 2, 3]
dostać [0, 3, 6, 9]
.
Chciałbym ograniczyć programistę, aby dać konstruktorowi MyList
listę, która jest również RandomAccess
, aby upewnić się, że nie zepsuje osiągów.
Próbowałem zmienić konstruktora z:
public <E extends List<Integer> & RandomAccess> MyList(int multiplier, E list)
MyList
nie jest problem, ale teraz nie możemy wywołać konstruktora bez używania implementację zarówno List<Integer>
i RandomAccess
jak ArrayList<Integer>
. Więc ktoś, kto ma tę listę: List<Integer> list = new ArrayList<>();
nie może zrobić new MyList(3, list);
(ponieważ jest zadeklarowana z List<Integer>
zamiast ArrayList<Integer>
).
Innym rozwiązaniem mam jest to jedno:
public MyList(int multiplier, List<Integer> list) {
if(!(list instanceof RandomAccess)) {
// Do something like log or throw exception
}
this.multiplier = multiplier;
this.list = list;
}
Ale teraz nie mogę sprawdzić w czasie kompilacji, jeśli lista implementuje RandomAccess
i muszę korzystać instanceof
i nienawidzę tego.
Jestem całkiem pewien, że istnieje lepszy sposób, ale co to jest?
Spróbuj użyć | (lub operator) zamiast operatora & (i operatora). Nie jestem pewien, czy to zadziała, ale warto spróbować. – MLavrentyev
Więc jeśli chcesz ograniczyć programistę do 'RandomAccess' _", aby upewnić się, że nie zepsuje on osiągów "_, to dlaczego nadal chciałbyś zezwolić im na wywołanie twojego konstruktora za pomocą' List', co oczywiście nie implementuje 'RandomAccess'? Czy to tylko ze względów kosmetycznych? –
Muszę wywołać 'List.get()'. – Happy