Перетворення "ArrayList <String> в" String [] "на Java


1022

Як я можу перетворити ArrayList<String>об’єкт у String[]масив на Java?


2
Зробили цю відповідь оновленим підходом до JDK-11, вводячи новий API з однаковою ефективністю toArray(T[])та подібний у синтаксисі до Stream.toArray.
Наман

Відповіді:


1788
List<String> list = ..;
String[] array = list.toArray(new String[0]);

Наприклад:

List<String> list = new ArrayList<String>();
//add some stuff
list.add("android");
list.add("apple");
String[] stringArray = list.toArray(new String[0]);

toArray()Метод без передачі яких - які аргументи повертаються Object[]. Отже, ви повинні передати масив як аргумент, який буде заповнений даними зі списку та повернутий. Ви можете також пропустити порожній масив, але можна також пропустити масив із потрібним розміром.

Важливе оновлення : спочатку використовуваний код вище new String[list.size()]. Однак цей блог показує, що завдяки оптимізаціям JVM new String[0]зараз краще використовувати .


16
Чи має значення розмір аргументу?
Thorbjørn Ravn Andersen

37
це рятує ще одне інстинктування масиву
Божо

59
Виявляється, надання масиву нульової довжини, навіть створення його та викидання, в середньому швидше, ніж виділення масиву потрібного розміру. Про орієнтири та пояснення дивіться тут: shipilev.net/blog/2016/arrays-wisdom-ancients
Stuart Marks

2
(Вибачте. Риторичне запитання. Відповідь, звичайно, тому, що Java не робить справжніх дженериків; вони здебільшого просто підробляють їх, кидаючи Object)
Nyerguds

3
@lyuboslavkanev Проблема полягає в тому, що наявності загального типу в Java недостатньо для фактичного створення об'єктів на основі цього типу; навіть не масив (що смішно, бо це повинно працювати для будь-якого типу). Все, що можна зробити з цим, наскільки я бачу, це кастинг. Насправді, щоб навіть створити об’єкти типу, вам потрібно мати власне Classоб'єкт, який, здається, неможливо вивести із загального типу. Як я вже казав, причина цього полягає в тому, що вся конструкція є фальшивою; все це просто зберігається як Об'єкт внутрішньо.
Nyerguds

170

Альтернатива на Java 8:

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

Java 11+:

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

25
Або якісь переваги?
Джеймс Уоткінс

1
Я вважаю за краще цей синтаксис, але IntelliJ відображає помилку компілятора з цим, скаржиться, що "T [] не є функціональним інтерфейсом".
Глен Мацца

3
@GlenMazza ви можете використовувати лише toArrayна Streamоб'єкті. Ця помилка компіляції може виникнути, якщо зменшити потік за допомогою a, Collectorsа потім спробувати застосувати toArray.
Удара Бентота

39

Ви можете використовувати toArray()метод для List:

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

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

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

Або ви можете вручну додати елементи до масиву:

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);
}

Сподіваюся, це допомагає!


30
ArrayList<String> arrayList = new ArrayList<String>();
Object[] objectList = arrayList.toArray();
String[] stringArray =  Arrays.copyOf(objectList,objectList.length,String[].class);

Використання copyOf, ArrayList для масивів також може бути зроблено.


4
Запропонуйте верблюд так "objectList = ..." та "stringArray". Крім того, це Arrays.copyOf ... capital O.
Jason Weden

1
list.toArray () використовує внутрішньо Arrays.copyOf ()
Девід

25

Починаючи з Java-11, можна альтернативно використовувати API, Collection.toArray(IntFunction<T[]> generator)щоб досягти того самого:

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

10

На Java 8:

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

12
Це дійсно вже міститься у цій відповіді . Можливо, додайте його як редагування до цієї відповіді, а не як абсолютно нову.
Річка

11
Чому parallelStream()замість просто stream()?
Yoory N.

7

У Java 8 це можна зробити за допомогою

String[] arrayFromList = fromlist.stream().toArray(String[]::new);

6

Дженерики рішення для перетворення будь-якого List<Type>в 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;
}

Примітка. Ви повинні використовувати override toString()метод.

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);

5
List <String> list = ...
String[] array = new String[list.size()];
int i=0;
for(String s: list){
  array[i++] = s;
}

13
Це працює, але не надто ефективно, і дублює функціональність у прийнятій відповіді із додатковим кодом.
Алан Делімон

5

у випадку, якщо потрібні додаткові маніпуляції з даними, для яких користувач хоче функцію, такий підхід не є ідеальним (оскільки вимагає передачі класу елемента як другого параметра), але працює:

імпорт java.util.ArrayList; імпорт 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()));
  }
}

5

Якщо у вашій програмі вже використовується вкладка Apache Commons, ви можете трохи змінити прийняту відповідь, щоб не створювати новий порожній масив кожен раз:

List<String> list = ..;
String[] array = list.toArray(ArrayUtils.EMPTY_STRING_ARRAY);

// or if using static import
String[] array = list.toArray(EMPTY_STRING_ARRAY);

Є ще кілька попередньо розподілених порожніх масивів різних типів у ArrayUtils.

Також ми можемо обдурити JVM, щоб створити en порожній масив для нас таким чином:

String[] array = list.toArray(ArrayUtils.toArray());

// or if using static import
String[] array = list.toArray(toArray());

Але в цьому дійсно немає переваги, лише питання смаку, ІМО.


5

Ви можете використовувати Iterator<String>для ітерації елементів 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();
}

Тепер ви можете отримати елементи з String[]використання будь-якого циклу.


Я прихильнився тому, що: 1. не використовуйте дженерики, які змушують вас .toString()зайнятись 2. використовувати там, де не потрібен чіткий ролик , 3. ви навіть не збільшуєтесь i, і 4. whileкраще буде замінити на for. Рекомендований код: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(); }
Олів'є Грегоар

Гаразд, я це зараз зрозумів. Дякую.
Ватсал Чавда

Ну, в ідеалі, вам слід відредагувати свій код, щоб включити ці коментарі (тобто ... якщо ви думаєте, що вони добре відповідають на вашу відповідь!). Я не буду розглядати питання про видалення мого поточного голосу, поки код не зміниться.
Олів'є Грегоар

Я тут новий, тому ще не знаю, як тут все працює. Хоча, оцініть свою допомогу.
Ватсал Чавда

Це набагато краще! Я трохи відредагував, але ви лише пережили, як це працює: дайте відповідь, вдосконаліть їх, отримайте лаври;)
Олів'є Грегоар


4
    List<String> list = new ArrayList<>();
    list.add("a");
    list.add("b");
    list.add("c");
    String [] strArry= list.stream().toArray(size -> new String[size]);

За коментарі я додав абзац, щоб пояснити, як працює конверсія. По-перше, список перетворюється на потік String. Потім він використовує Stream.toArray для перетворення елементів у потоці в масив. В останньому твердженні вище "size -> new String [size]" - це фактично функція IntFunction, яка виділяє String масив розміром потоку String. Заява ідентична

IntFunction<String []> allocateFunc = size -> { 
return new String[size];
};   
String [] strArry= list.stream().toArray(allocateFunc);

4
Яке значення додає ця відповідь? Здається, просто повторюйте інші відповіді, не пояснюючи, чому це відповідає на питання.
Річард

2

Ви можете конвертувати список у масив String, використовуючи цей метод:

 Object[] stringlist=list.toArray();

Повний приклад:

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]);
    }

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.