Przede wszystkim mogę się tylko zgodzić, że Arrays.asList(T...)
jest to zdecydowanie najlepsze rozwiązanie dla typów Wrapper lub tablic z innymi niż pierwotne typy danych. Ta metoda wywołuje konstruktor prostej prywatnej AbstractList
implementacji statycznej w Arrays
klasie, która w zasadzie zapisuje podane odwołanie do tablicy jako pole i symuluje listę, zastępując potrzebne metody.
Jeśli możesz wybrać typ pierwotny lub typ Wrapper dla swojej tablicy, użyłbym typu Wrapper w takich sytuacjach, ale oczywiście nie zawsze jest on przydatny lub wymagany. Byłyby tylko dwie możliwości, które możesz zrobić:
1) Możesz utworzyć klasę ze statyczną metodą dla każdej pierwotnej tablicy typu danych ( boolean, byte, short, int, long, char, float, double
zwracając Iterable<
WrapperType >
. Te metody używałyby anonimowych klas Iterator
(pozaIterable
), które mogą zawierać odwołanie do argumentu metody zawierającej (na przykład int[]
) jako pole w celu zaimplementowania metod.
-> To podejście jest wydajne i oszczędza pamięć (z wyjątkiem pamięci nowo utworzonych metod, chociaż użycie Arrays.asList()
zajmie pamięć w ten sam sposób)
2) Ponieważ tablice nie mają metod (jak do odczytu z boku z linkiem), nie mogą też zapewnić Iterator
instancji. Jeśli naprawdę jesteś zbyt leniwy, aby pisać nowe klasy, musisz użyć instancji już istniejącej klasy, która implementuje, Iterable
ponieważ nie ma innego wyjścia niż utworzenie instancji Iterable
lub podtyp.
JEDYNY sposób na utworzenie istniejącej implementacji pochodnej kolekcjiIterable
polega na użyciu pętli (z wyjątkiem używania klas anonimowych, jak opisano powyżej) lub utworzeniu instancji Iterable
klasy implementującej, której konstruktor zezwala na tablicę typu pierwotnego (ponieważ Object[]
nie zezwala na tablice z elementami typu pierwotnego), ale o ile wiem, API Java nie ma takiej klasy.
Powód pętli można łatwo wyjaśnić:
dla każdej kolekcji potrzebujesz Obiekty, a pierwotne typy danych nie są obiektami. Obiekty są znacznie większe niż typy pierwotne, dlatego wymagają dodatkowych danych, które muszą zostać wygenerowane dla każdego elementu tablicy typów pierwotnych. Oznacza to, że jeśli dwa z trzech sposobów (używanie Arrays.asList(T...)
lub używanie istniejącej kolekcji) wymagają agregacji obiektów, musisz utworzyć dla każdej pierwotnej wartości swojejint[]
w szyku obiekt opakowania. Trzeci sposób użyłby tablicy w takiej postaci, w jakiej jest, i użyłby jej w klasie anonimowej, ponieważ uważam, że jest to preferowane ze względu na dużą wydajność.
Istnieje również trzecia strategia wykorzystująca Object
argument jako argument dla metody, w której chcesz użyć tablicy lub Iterable
która wymagałaby sprawdzenia typu, aby dowiedzieć się, jaki typ ma argument, jednak nie polecałbym tego w ogóle, ponieważ zwykle musisz weź pod uwagę, że Object nie zawsze ma wymagany typ i że w niektórych przypadkach potrzebujesz osobnego kodu.
Podsumowując, jest to wina problematycznego systemu typów ogólnych w Javie, który nie pozwala na użycie typów pierwotnych jako typów ogólnych, co pozwoliłoby zaoszczędzić dużo kodu, używając prostegoArrays.asList(T...)
. Więc musisz zaprogramować taką metodę dla każdej tablicy typów pierwotnych (która w zasadzie nie robi różnicy w pamięci używanej przez program w C ++, który utworzyłby dla każdego użytego argumentu typu oddzielną metodę.