Konwertowanie „ArrayList <String> na„ String [] ”w Javie

1022

Jak mogę przekonwertować ArrayList<String>obiekt na String[]tablicę w Javie?

Alex
źródło
2
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(new String[0]);

Na przykład:

List<String> list = new ArrayList<String>();
//add some stuff
list.add("android");
list.add("apple");
String[] stringArray = list.toArray(new String[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.

Bozho
źródło
16
Czy wielkość argumentu robi jakąkolwiek różnicę?
Thorbjørn Ravn Andersen
37
oszczędza to jeszcze jedną instancję
Bozho
59
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.
Nyerguds,
170

Alternatywa w Javie 8:

String[] strings = list.stream().toArray(String[]::new);

Java 11+:

String[] strings = list.toArray(String[]::new);
Vitalii Fedorenko
źródło
25
Czy jakieś korzyści?
James Watkins,
1
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 = new ArrayList<String>();

list.add("apple");
list.add("banana");

String[] array = list.toArray(new String[list.size()]);

Lub możesz ręcznie dodać elementy do tablicy:

ArrayList<String> list = new ArrayList<String>();

list.add("apple");
list.add("banana");

String[] array = new String[list.size()];

for (int i = 0; i < list.size(); i++) {
    array[i] = list.get(i);
}

Mam nadzieję że to pomoże!

kodowane
źródło
30
ArrayList<String> arrayList = new ArrayList<String>();
Object[] objectList = arrayList.toArray();
String[] stringArray =  Arrays.copyOf(objectList,objectList.length,String[].class);

Używanie copyOf, ArrayList do tablic może być również wykonane.

Rajesh Vemula
źródło
4
Zaproponuj camelcase, aby „objectList = ...” i „stringArray”. Poza tym jest to Arrays.copyOf ... kapitału O.
Jason Weden
1
list.toArray () wewnętrznie używa Arrays.copyOf ()
David
25

Począwszy od Java-11, można alternatywnie użyć interfejsu API, Collection.toArray(IntFunction<T[]> generator)aby osiągnąć to samo, co:

List<String> list = List.of("x","y","z");
String[] arrayBeforeJDK11 = list.toArray(new String[0]);
String[] arrayAfterJDK11 = list.toArray(String[]::new); // similar to Stream.toArray
Naman
źródło
10

W Javie 8:

String[] strings = list.parallelStream().toArray(String[]::new);
Mike Shauneu
źródło
12
To jest naprawdę zawarte w tej odpowiedzi . Być może dodaj ją jako edycję do tej odpowiedzi zamiast zupełnie nowej.
Rzeka
11
Dlaczego parallelStream()zamiast po prostu stream()?
Yoory N.
7

W Javie 8 można to zrobić za pomocą

String[] arrayFromList = fromlist.stream().toArray(String[]::new);
KayV
źródło
6

Leki generyczne rozwiązanie przekształca dowolny List<Type>do String []:

public static  <T> String[] listToArray(List<T> list) {
    String [] array = new String[list.size()];
    for (int i = 0; i < array.length; i++)
        array[i] = list.get(i).toString();
    return array;
}

Uwaga Musisz wykonać override toString()metodę.

class Car {
  private String name;
  public Car(String name) {
    this.name = name;
  }
  public String toString() {
    return name;
  }
}
final List<Car> carList = new ArrayList<Car>();
carList.add(new Car("BMW"))
carList.add(new Car("Mercedes"))
carList.add(new Car("Skoda"))
final String[] carArray = listToArray(carList);
Khaled Lela
źródło
5
List <String> list = ...
String[] array = new String[list.size()];
int i=0;
for(String s: list){
  array[i++] = s;
}
HZhang
źródło
13
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:

import java.util.ArrayList; import java.lang.reflect.Array;

public class Test {
  public static void main(String[] args) {
    ArrayList<Integer> al = new ArrayList<>();
    al.add(1);
    al.add(2);
    Integer[] arr = convert(al, Integer.class);
    for (int i=0; i<arr.length; i++)
      System.out.println(arr[i]);
  }

  public static <T> T[] convert(ArrayList<T> al, Class clazz) {
    return (T[]) al.toArray((T[])Array.newInstance(clazz, al.size()));
  }
}
Roberto Attias
źródło
5

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 import
String[] 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 import
String[] array = list.toArray(toArray());

Ale tak naprawdę nie ma żadnej przewagi, tylko kwestia gustu, IMO.

Yoory N.
źródło
5

Możesz użyć Iterator<String>do iteracji elementów ArrayList<String>:

ArrayList<String> list = new ArrayList<>();
String[] array = new String[list.size()];
int i = 0;
for (Iterator<String> iterator = list.iterator(); iterator.hasNext(); i++) {
    array[i] = iterator.next();
}

Teraz możesz wycofać elementy z String[]użycia dowolnej pętli.

Vatsal Chavda
źródło
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)

z java.base's java.util.Collection.toArray() .

Rafał Borowiec
źródło
4
    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    String [] strArry= list.stream().toArray(size -> new String[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

IntFunction<String []> allocateFunc = size -> { 
return new String[size];
};   
String [] strArry= list.stream().toArray(allocateFunc);
nick w.
źródło
4
Jaką wartość ma ta odpowiedź? Wydaje się, że po prostu powtarza inne odpowiedzi bez wyjaśnienia, dlaczego odpowiada na pytanie.
Richard
2

Możesz przekonwertować List na tablicę String, używając tej metody:

 Object[] stringlist=list.toArray();

Kompletny przykład:

ArrayList<String> list=new ArrayList<>();
    list.add("Abc");
    list.add("xyz");

    Object[] stringlist=list.toArray();

    for(int i = 0; i < stringlist.length ; i++)
    {
          Log.wtf("list data:",(String)stringlist[i]);
    }
Panchal Nilkanth
źródło
1
private String[] prepareDeliveryArray(List<DeliveryServiceModel> deliveryServices) {
    String[] delivery = new String[deliveryServices.size()];
    for (int i = 0; i < deliveryServices.size(); i++) {
        delivery[i] = deliveryServices.get(i).getName();
    }
    return delivery;
}
Denis Fedak
źródło