To może być trochę łatwe pytanie w rodzaju headdesku, ale moja pierwsza próba zaskakująco kompletnie się nie powiodła. Chciałem wziąć tablicę prymitywnych tęsknot i przekształcić ją w listę, którą próbowałem zrobić w następujący sposób:
long[] input = someAPI.getSomeLongs();
List<Long> inputAsList = Arrays.asList(input); //Total failure to even compile!
Jaki jest właściwy sposób, aby to zrobić?
java
arrays
collections
boxing
Brandon Yarbrough
źródło
źródło
Odpowiedzi:
Uważam, że wygodnie jest używać apache commons lang ArrayUtils ( zależność JavaDoc , Maven )
ma również odwrotne API
EDYCJA: zaktualizowano, aby zapewnić pełną konwersję do listy, zgodnie z sugestiami i innymi poprawkami.
źródło
Arrays.asList(ArrayUtils.toObject(input))
prawdopodobnie mogą to łatwo zrobić .List<Long> = Arrays.asList(inputBoxed)
w ich pytaniu uznałem za zbędne powtarzanie go, ponieważ myślałem, że to oczywiste, myślę, że się myliłem ...Od wersji Java 8 możesz teraz używać do tego strumieni:
źródło
stream
funkcja jest zdefiniowana tylko dlaint[]
,long[]
idouble[]
.LongStream.of(arr).boxed()...
.Arrays.stream(arr).boxed().collect(Collectors.toList());
Niestety to może powrócićList<Object>
źródło
hallidave i jpalecek mają dobry pomysł - iterując po tablicy - ale nie korzystają z funkcji dostarczonej przez
ArrayList
: ponieważ rozmiar listy jest w tym przypadku znany , powinieneś określić go podczas tworzeniaArrayList
.W ten sposób żadne niepotrzebne tablice nie są tworzone tylko po to, aby je wyrzucić,
ArrayList
ponieważ okazują się zbyt krótkie, a puste "gniazda" nie są marnowane, ponieważArrayList
przeszacowano jego wymagania przestrzenne. Oczywiście, jeśli będziesz nadal dodawać elementy do listy, potrzebna będzie nowa tablica zapasowa.źródło
Nieco bardziej szczegółowe, ale to działa:
W twoim przykładzie wygląda na to, że Arrays.asList () interpretuje dane wejściowe jako listę tablic long [] zamiast listy Longs. Na pewno trochę zaskakujące. W tym przypadku autoboxing po prostu nie działa tak, jak tego chcesz.
źródło
Jako kolejną możliwość, biblioteka Guava zapewnia to podobnie jak
Longs.asList()
w przypadku podobnych klas użytkowych dla innych typów pierwotnych.źródło
Nie, nie ma automatycznej konwersji z tablicy typu pierwotnego na tablicę ich opakowanych typów odwołań. Możesz tylko to zrobić
źródło
Pytanie dotyczyło tego, jak zamienić tablicę w listę. Większość dotychczasowych odpowiedzi pokazywała, jak utworzyć nową listę z taką samą zawartością jak tablica lub z odniesieniami do bibliotek innych firm. Istnieją jednak proste, wbudowane opcje tego rodzaju konwersji. Niektóre z nich zostały już naszkicowane w innych odpowiedziach (np. W tej ). Chciałbym jednak wskazać i rozwinąć tutaj pewne stopnie swobody dla implementacji oraz pokazać potencjalne korzyści, wady i zastrzeżenia.
Należy dokonać co najmniej dwóch ważnych rozróżnień:
Opcje zostaną tutaj szybko podsumowane, a pełny przykładowy program jest pokazany na dole tej odpowiedzi.
Tworzenie nowej listy a tworzenie widoku na tablicy
Jeśli wynikiem powinna być nowa lista, można zastosować jedno z podejść z innych odpowiedzi:
Należy jednak wziąć pod uwagę wady takiego działania: tablica zawierająca 1000000
long
wartości zajmie około 8 megabajtów pamięci. Nowa lista zajmie również około 8 megabajtów. Oczywiście podczas tworzenia tej listy należy przejść przez całą tablicę. W wielu przypadkach tworzenie nowej listy po prostu nie jest konieczne. Zamiast tego wystarczy stworzyć widok na tablicy:(Zobacz przykład na dole, aby zobaczyć implementację
toList
metody)Konsekwencją posiadania widoku tablicy jest to, że zmiany w tablicy będą widoczne na liście:
Na szczęście utworzenie kopii (czyli nowej listy, na którą nie mają wpływu modyfikacje tablicy) z widoku jest trywialne:
To jest prawdziwa kopia, równoważna temu, co osiągnięto dzięki rozwiązaniu opartemu na strumieniu, które zostało pokazane powyżej.
Tworzenie modyfikowalnego widoku lub niemodyfikowalnego widoku
W wielu przypadkach wystarczy, że lista jest tylko do odczytu . Zawartość listy wynikowej często nie jest modyfikowana, a jedynie przekazywana do dalszego przetwarzania, które tylko odczytuje listę.
Dopuszczenie modyfikacji listy rodzi kilka pytań:
Możliwe jest utworzenie widoku listy w tablicy, którą można modyfikować . Oznacza to, że zmiany na liście, takie jak ustawienie nowej wartości w określonym indeksie, będą widoczne w tablicy.
Nie jest jednak możliwe utworzenie widoku listy, który można modyfikować strukturalnie . Oznacza to, że nie można wykonywać operacji, które mają wpływ na rozmiar listy. Dzieje się tak po prostu dlatego, że nie można zmienić rozmiaru tablicy bazowej .
Poniżej znajduje się MCVE pokazujący różne opcje implementacji i możliwe sposoby wykorzystania wynikowych list:
Dane wyjściowe przykładu pokazano tutaj:
źródło
Inny sposób z Javą 8.
źródło
Piszę małą bibliotekę dla tych problemów:
Jeśli chcesz, sprawdź to tutaj .
źródło
Inny sposób z Javą 8.
źródło
Arrays.stream(a).boxed().collect(Collectors.<Long>toList());
Łącząc odpowiedzi Pawła i Toma otrzymujemy to
źródło
Jeśli chcesz mieć podobną semantykę
Arrays.asList
, musisz napisać (lub użyć cudzej) implementacji klientaList
(prawdopodobnie przezAbstractList
. Powinna mieć taką samą implementację, jakArrays.asList
tylko wartości box i unbox).źródło
Możesz użyć transmorfii :
Działa również, jeśli source jest na przykład tablicą liczb int.
źródło
Wiem, że to pytanie jest wystarczająco stare, ale ... możesz też napisać własną metodę konwersji:
Po dołączeniu go za pomocą importu statycznego możliwe zastosowania mogą być:
lub
źródło
catch (ArrayIndexOutOfBoundsException ex) { /* Finished getting array elements */ }
jesteś okropną osobą.Chociaż możliwe jest utworzenie nowej listy i dodanie do niej wszystkich wartości (za pośrednictwem pętli for lub strumieni), pracowałem nad naprawdę dużymi tablicami i uzyskiwałem słabą wydajność. Dlatego stworzyłem własną, łatwą w użyciu, prostą klasę opakowania tablicy.
Przykład:
Pobierz tutaj: https://github.com/Sf298/Sauds-Toolbox/blob/master/src/main/java/PrimitiveArrayWrapper/PrimitiveList.java
UWAGA: nie przetestowałem go jeszcze w pełni, więc daj mi znać, jeśli znajdziesz jakieś błędy / problemy.
źródło
Możesz użyć
LongStream
do tegoźródło