strings - string stream to array java




Преобразовать ArrayList<String> в String[] array (4)

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

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

На этот вопрос уже есть ответ:

Я работаю в среде Android и пробовал следующий код, но он, похоже, не работает.

String [] stockArr = (String[]) stock_list.toArray();

Если я определяю следующее:

String [] stockArr = {"hello", "world"};

оно работает. Есть что-то, что мне не хватает?


Используйте вот так.

List<String> stockList = new ArrayList<String>();
stockList.add("stock1");
stockList.add("stock2");

String[] stockArr = new String[stockList.size()];
stockArr = stockList.toArray(stockArr);

for(String s : stockArr)
    System.out.println(s);

Правильный способ сделать это:

String[] stockArr = stock_list.toArray(new String[stock_list.size()]);

Я хотел бы добавить к другим замечательным ответам здесь и объяснить, как вы могли использовать Javadocs для ответа на ваш вопрос.

Javadoc для toArray() (без аргументов) here . Как вы можете видеть, этот метод возвращает Object[] а не String[] который является массивом типа среды выполнения вашего списка:

public Object[] toArray()

Возвращает массив, содержащий все элементы в этой коллекции. Если коллекция делает какие-либо гарантии относительно того, какой порядок возвращает ее элемент своим итератором, этот метод должен возвращать элементы в том же порядке. Возвращенный массив будет «безопасным», поскольку ссылки на него не поддерживаются коллекцией. (Другими словами, этот метод должен выделять новый массив, даже если коллекция поддерживается массивом). Таким образом, вызывающий абонент может изменять возвращаемый массив.

Прямо под этим методом, однако, является Javadoc для toArray(T[] a) . Как вы можете видеть, этот метод возвращает T[] где T - тип массива, в который вы проходите. Сначала это похоже на то, что вы ищете, но неясно, почему именно вы передаете массив ( вы добавляете к нему, используя его только для типа и т. д.). Документация дает понять, что цель переданного массива состоит в том, чтобы определить тип возвращаемого массива (который является именно вашим прецедентом):

public <T> T[] toArray(T[] a)

Возвращает массив, содержащий все элементы в этой коллекции; тип выполнения возвращаемого массива - тип указанного массива. Если коллекция подходит в указанном массиве, она возвращается в нее. В противном случае новому массиву присваивается тип среды выполнения указанного массива и размер этой коллекции. Если коллекция подходит в указанном массиве с запасной комнатой (т. Е. Массив имеет больше элементов, чем коллекция), элемент в массиве сразу же после окончания коллекции устанавливается в нуль. Это полезно при определении длины коллекции, только если вызывающий абонент знает, что коллекция не содержит никаких нулевых элементов.)

Если этот сборник дает какие-либо гарантии относительно того, каким порядком его элементы возвращаются его итератором, этот метод должен возвращать элементы в том же порядке.

Эта реализация проверяет, достаточно ли массив достаточно содержать коллекцию; если нет, он выделяет новый массив правильного размера и типа (используя отражение). Затем он выполняет итерацию по коллекции, сохраняя каждую ссылку на объект в следующем последовательном элементе массива, начиная с элемента 0. Если массив больше, чем коллекция, нуль хранится в первом месте после окончания коллекции.

Конечно, понимание дженериков (как описано в других ответах) необходимо для понимания разницы между этими двумя методами. Тем не менее, если вы впервые отправитесь в Javadocs, вы, как правило, найдете свой ответ, а затем сами убедитесь, что еще нужно изучить (если вы действительно это делаете).

Также обратите внимание, что чтение Javadocs здесь поможет вам понять, какова должна быть структура массива, в который вы проходите. Хотя это может и не иметь особого значения, вы не должны проходить в таком пустом массиве, как это:

String [] stockArr = stockList.toArray(new String[0]);  

Поскольку, из документа, эта реализация проверяет, достаточно ли массив достаточно содержать коллекцию; если нет, он выделяет новый массив правильного размера и типа (используя отражение). Нет необходимости в дополнительных накладных расходах при создании нового массива, когда вы можете легко передать размер.

Как обычно, Javadocs предоставляют вам массу информации и направлений.

Эй, подождите, что такое отражение?


Что происходит, так это то, что stock_list.toArray() создает Object[] а не String[] и, следовательно, при ошибке типа 1 не выполняется.

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

  String [] stockArr = stockList.toArray(new String[stockList.size()]);

или даже

  String [] stockArr = stockList.toArray(new String[0]);

Для получения дополнительной информации см. Javadocs для двух перегрузок List.toArray .

Последняя версия использует массив нулевой длины для определения типа массива результатов. (Удивительно, но это делается быстрее, чем предварительное распределение ... по крайней мере, для последних выпусков Java. Подробности см. На https://.com/a/4042464/139985 .)

С технической точки зрения причиной этого поведения / дизайна API является то, что реализация метода List<T>.toArray() не имеет информации о том, что <T> находится во время выполнения. Все, что он знает, это то, что тип raw-типа - Object . Напротив, в другом случае параметр массива дает базовый тип массива. (Если поставляемый массив достаточно велик, чтобы удерживать элементы списка, он используется. В противном случае в результате будет выделен и возвращен новый массив того же типа и большего размера.)

1 - В Java Object[] не является присвоением, совместимым со String[] . Если бы это было так, вы могли бы сделать это:

    Object[] objects = new Object[]{new Cat("fluffy")};
    Dog[] dogs = (Dog[]) objects;
    Dog d = dogs[0];     // Huh???

Это явно бессмыслица, и поэтому типы массивов обычно не совместимы с назначением.





arraylist