Posiadane wykonane tę odpowiedź z uaktualnionym podejścia z JDK-11 wprowadza nowy równie wydajnych API toArray(T[])i podobny w składni Stream.toArray.
Naman
Odpowiedzi:
1788
List<String> list =..;String[] array = list.toArray(newString[0]);
Na przykład:
List<String> list =newArrayList<String>();//add some stuff
list.add("android");
list.add("apple");String[] stringArray = list.toArray(newString[0]);
toArray()Metoda nie przechodząc żadnych zwrotów argumentów Object[]. Musisz więc przekazać tablicę jako argument, który zostanie wypełniony danymi z listy i zwrócony. Możesz również przekazać pustą tablicę, ale możesz również przekazać tablicę o pożądanym rozmiarze.
Ważna aktualizacja : pierwotnie użyty powyższy kod new String[list.size()]. Jednak ten blog pokazuje, że ze względu na optymalizację JVM korzystanie z niego new String[0]jest teraz lepsze.
Okazuje się, że dostarczenie tablicy zerowej długości, nawet jej utworzenie i wyrzucenie, jest średnio szybsze niż przydzielenie tablicy o odpowiednim rozmiarze. Aby zapoznać się z wynikami
Stuart Marks
2
(Przepraszam. Pytanie retoryczne. Odpowiedź brzmi oczywiście, ponieważ Java nie robi prawdziwych generyków; przeważnie po prostu podrabia je rzucając Object)
Nyerguds
3
@lyuboslavkanev Problem polega na tym, że posiadanie ogólnego typu w Javie nie wystarcza do tworzenia obiektów na podstawie tego typu; nawet tablica (co jest śmieszne, ponieważ powinno to działać dla każdego typu). O ile mi wiadomo, wszystko, co można z tym zrobić, to casting. W rzeczywistości, aby nawet tworzyć obiekty tego typu, musisz mieć rzeczywisty Classobiekt, który wydaje się całkowicie niemożliwy do uzyskania na podstawie typu ogólnego. Powodem tego, jak powiedziałem, jest to, że cała konstrukcja jest fałszywa; wszystko jest po prostu przechowywane wewnętrznie jako Obiekt.
Wolałbym tę składnię, ale IntelliJ wyświetla przy tym błąd kompilatora, narzeka „T [] nie jest funkcjonalnym interfejsem”.
Glen Mazza,
3
@GlenMazza możesz używać tylko toArrayna Streamobiekcie. Ten błąd kompilacji może wystąpić, jeśli zmniejszysz strumień za pomocą a, Collectorsa następnie spróbujesz zastosować toArray.
Udara Bentota
39
Możesz użyć tej toArray()metody do List:
ArrayList<String> list =newArrayList<String>();
list.add("apple");
list.add("banana");String[] array = list.toArray(newString[list.size()]);
Lub możesz ręcznie dodać elementy do tablicy:
ArrayList<String> list =newArrayList<String>();
list.add("apple");
list.add("banana");String[] array =newString[list.size()];for(int i =0; i < list.size(); i++){
array[i]= list.get(i);}
List<String> list =List.of("x","y","z");String[] arrayBeforeJDK11 = list.toArray(newString[0]);String[] arrayAfterJDK11 = list.toArray(String[]::new);// similar to Stream.toArray
Działa to, ale nie jest super wydajne i powiela funkcjonalność w przyjętej odpowiedzi z dodatkowym kodem.
Alan Delimon
5
w przypadku, gdy pożądana jest dodatkowa manipulacja danymi, dla której użytkownik chce funkcji, to podejście nie jest idealne (ponieważ wymaga przekazania klasy elementu jako drugiego parametru), ale działa:
Jeśli Twoja aplikacja korzysta już z biblioteki Apache Commons lib, możesz nieznacznie zmodyfikować zaakceptowaną odpowiedź, aby za każdym razem nie tworzyć nowej pustej tablicy:
List<String> list =..;String[] array = list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);// or if using static importString[] array = list.toArray(EMPTY_STRING_ARRAY);
Istnieje jeszcze kilka wstępnie przydzielonych pustych tablic różnych typów ArrayUtils.
Możemy również oszukać JVM, aby utworzył dla nas pustą tablicę w ten sposób:
String[] array = list.toArray(ArrayUtils.toArray());// or if using static importString[] array = list.toArray(toArray());
Ale tak naprawdę nie ma żadnej przewagi, tylko kwestia gustu, IMO.
Odrzuciłem głos, ponieważ: 1. brak użycia ogólnych, które zmusiłyby cię do 2. użycia, .toString()gdzie nie byłoby konieczne użycie jawnej obsady, 3. nawet nie zwiększania i, i 4. whilelepiej byłoby zastąpić przez for. Sugerowany kod:ArrayList<String> stringList = ... ; String[] stringArray = new String[stringList.size()]; int i = 0; for(Iterator<String> it = stringList.iterator(); it.hasNext(); i++) { stringArray[i] = it.next(); }
Olivier Grégoire
Okej, teraz to rozumiem. Dzięki.
Vatsal Chavda
Idealnie, powinieneś edytować swój kod, aby uwzględnić te komentarze (to znaczy ... jeśli uważasz, że są dobre dla twojej odpowiedzi!). Nie będę rozważał usunięcia mojego downvote, dopóki kod pozostanie niezmieniony.
Olivier Grégoire
Jestem tu nowy, więc jeszcze nie wiem, jak to działa. Chociaż doceń swoją pomoc.
Vatsal Chavda
To jest dużo lepsze! Ja tylko trochę zredagowałem, ale właśnie doświadczyłeś, jak to działa: podaj odpowiedź, popraw je, zdobądź laury;)
Olivier Grégoire
5
W Javie 11 możemy użyć tej Collection.toArray(generator)metody. Poniższy kod utworzy nową tablicę ciągów:
List<String> list =List.of("one","two","three");String[] array = list.toArray(String[]::new)
List<String> list =newArrayList<>();
list.add("a");
list.add("b");
list.add("c");String[] strArry= list.stream().toArray(size ->newString[size]);
Do komentarzy dodałem akapit wyjaśniający, jak działa konwersja. Po pierwsze, List jest konwertowany na strumień String. Następnie używa Stream.toArray do konwersji elementów w strumieniu na tablicę. W ostatniej instrukcji powyżej „size -> new String [size]” to tak naprawdę funkcja IntFunction, która przydziela tablicę String o rozmiarze strumienia String. Instrukcja jest identyczna z
toArray(T[])
i podobny w składniStream.toArray
.Odpowiedzi:
Na przykład:
toArray()
Metoda nie przechodząc żadnych zwrotów argumentówObject[]
. Musisz więc przekazać tablicę jako argument, który zostanie wypełniony danymi z listy i zwrócony. Możesz również przekazać pustą tablicę, ale możesz również przekazać tablicę o pożądanym rozmiarze.Ważna aktualizacja : pierwotnie użyty powyższy kod
new String[list.size()]
. Jednak ten blog pokazuje, że ze względu na optymalizację JVM korzystanie z niegonew String[0]
jest teraz lepsze.źródło
Class
obiekt, który wydaje się całkowicie niemożliwy do uzyskania na podstawie typu ogólnego. Powodem tego, jak powiedziałem, jest to, że cała konstrukcja jest fałszywa; wszystko jest po prostu przechowywane wewnętrznie jako Obiekt.Alternatywa w Javie 8:
Java 11+:
źródło
toArray
naStream
obiekcie. Ten błąd kompilacji może wystąpić, jeśli zmniejszysz strumień za pomocą a,Collectors
a następnie spróbujesz zastosowaćtoArray
.Możesz użyć tej
toArray()
metody doList
:Lub możesz ręcznie dodać elementy do tablicy:
Mam nadzieję że to pomoże!
źródło
Używanie copyOf, ArrayList do tablic może być również wykonane.
źródło
Począwszy od Java-11, można alternatywnie użyć interfejsu API,
Collection.toArray(IntFunction<T[]> generator)
aby osiągnąć to samo, co:źródło
W Javie 8:
źródło
parallelStream()
zamiast po prostustream()
?W Javie 8 można to zrobić za pomocą
źródło
Leki generyczne rozwiązanie przekształca dowolny
List<Type>
doString []
:Uwaga Musisz wykonać
override toString()
metodę.źródło
źródło
w przypadku, gdy pożądana jest dodatkowa manipulacja danymi, dla której użytkownik chce funkcji, to podejście nie jest idealne (ponieważ wymaga przekazania klasy elementu jako drugiego parametru), ale działa:
import java.util.ArrayList; import java.lang.reflect.Array;
źródło
Jeśli Twoja aplikacja korzysta już z biblioteki Apache Commons lib, możesz nieznacznie zmodyfikować zaakceptowaną odpowiedź, aby za każdym razem nie tworzyć nowej pustej tablicy:
Istnieje jeszcze kilka wstępnie przydzielonych pustych tablic różnych typów
ArrayUtils
.Możemy również oszukać JVM, aby utworzył dla nas pustą tablicę w ten sposób:
Ale tak naprawdę nie ma żadnej przewagi, tylko kwestia gustu, IMO.
źródło
Możesz użyć
Iterator<String>
do iteracji elementówArrayList<String>
:Teraz możesz wycofać elementy z
String[]
użycia dowolnej pętli.źródło
.toString()
gdzie nie byłoby konieczne użycie jawnej obsady, 3. nawet nie zwiększaniai
, i 4.while
lepiej byłoby zastąpić przezfor
. Sugerowany kod:ArrayList<String> stringList = ... ; String[] stringArray = new String[stringList.size()]; int i = 0; for(Iterator<String> it = stringList.iterator(); it.hasNext(); i++) { stringArray[i] = it.next(); }
W Javie 11 możemy użyć tej
Collection.toArray(generator)
metody. Poniższy kod utworzy nową tablicę ciągów:z java.base's
java.util.Collection.toArray()
.źródło
Do komentarzy dodałem akapit wyjaśniający, jak działa konwersja. Po pierwsze, List jest konwertowany na strumień String. Następnie używa Stream.toArray do konwersji elementów w strumieniu na tablicę. W ostatniej instrukcji powyżej „size -> new String [size]” to tak naprawdę funkcja IntFunction, która przydziela tablicę String o rozmiarze strumienia String. Instrukcja jest identyczna z
źródło
Możesz przekonwertować List na tablicę String, używając tej metody:
Kompletny przykład:
źródło
źródło