W3docs

Как преобразовать List в массив в Java

Преобразуйте Java List в массив с помощью toArray и подходов на основе stream.

List и массив хранят одни и те же элементы, но предоставляют разные API: List изменяет размер и имеет богатый набор методов, тогда как массив имеет фиксированную длину и используется многими старыми или низкоуровневыми API. Преобразование из одного в другое — это однострочная операция в современной Java; единственный реальный выбор — какой вариант лучше читается и нужен ли вам массив объектов или примитивов. На этой странице рассматривается типизированная перегрузка toArray, ссылка на конструктор в Java 11+, путь через stream для примитивных массивов и подводные камни безаргументного toArray().

Идиоматический способ: toArray с типизированным массивом

List.toArray(T[]) возвращает строго типизированный массив. Передайте массив нулевой длины нужного типа элемента и позвольте JDK самому определить размер результата:

List<String> names = List.of("Ann", "Bob", "Cy");
String[] arr = names.toArray(new String[0]);

Аргумент new String[0] передаёт тип (String[]), а не предварительно заданный буфер. На современных JVM форма с пустым массивом является рекомендуемой — она такая же быстрая, как массив точно заданного размера, и позволяет избежать ошибки, при которой слишком маленький массив перевыделяется, а слишком большой оставляет хвостовые null. Используйте этот подход всякий раз, когда вам нужен массив объектного типа, например String[], Integer[] или ваш собственный класс.

Форма Java 11+: ссылка на конструктор массива

Начиная с Java 11 можно передавать ссылку на конструктор массива вместо буквального пустого массива. Это выражает именно то, что имеется в виду — «сделай мне String[]»:

String[] arr = names.toArray(String[]::new);

Это компилируется в то же самое, что и new String[0], но читается понятнее. Обратите внимание: безаргументный toArray() — это ловушка: он всегда возвращает Object[], но не String[], поэтому приведение его результата к String[] бросает ClassCastException во время выполнения.

ПодходТип результатаПримечания
list.toArray(new String[0])String[]Рекомендуется для массивов объектов
list.toArray(String[]::new)String[]Java 11+, наиболее понятная форма
list.toArray()Object[]Теряет тип элемента; редко то, что нужно
list.stream().mapToInt(...).toArray()int[]Единственный способ получить примитивный массив

Примитивные массивы получают через stream

toArray может производить только массивы объектов. List<Integer> нельзя напрямую преобразовать в int[] — автоупаковка не распространяется на массивы. Используйте stream для распаковки каждого элемента:

List<Integer> nums = List.of(10, 20, 30);
int[] prim = nums.stream().mapToInt(Integer::intValue).toArray();

Тот же паттерн даёт вам long[] (mapToLong) и double[] (mapToDouble). В JDK нет специального сокращения для примитивных массивов, поэтому stream — это идиоматический путь.

Практический пример

Эта программа запускает все подходы параллельно, выводит тип времени выполнения, который на самом деле возвращает безаргументный toArray, и доказывает, что полученный массив является независимой копией — его редактирование не затрагивает исходный список.

java— editable, runs on the server

Что можно извлечь из запуска:

  • toArray(new String[0]) и toArray(String[]::new) оба выводят [Ann, Bob, Cy] — это два способа записи одного и того же типизированного преобразования, и вы можете выбрать тот, который лучше читается в вашем коде.
  • Безаргументный toArray() сообщает свой тип времени выполнения как Object[], а не String[] — наглядное доказательство того, что он стирает тип элемента, и почему следует избегать приведения его результата.
  • List<Integer> становится настоящим int[] только после mapToInt; выведенный [10, 20, 30] является примитивным массивом, а не Integer[], поэтому никакой упаковки не остаётся.
  • Arrays.stream(prim).sum() выводит 60, подтверждая, что результат является пригодным для использования примитивным массивом, который можно сразу передавать в числовые операции stream.
  • После a1[0] = "ZZ" массив выводит [ZZ, Bob, Cy], тогда как список по-прежнему выводит [Ann, Bob, Cy]toArray возвращает независимую копию, поэтому изменения массива никогда не попадают обратно в исходный список.

Практика

Практика
У вас есть List<Integer> и нужен int[]. Какое выражение правильно его создаёт?
У вас есть List<Integer> и нужен int[]. Какое выражение правильно его создаёт?
Was this page helpful?