Java: конвертируем поток в массив
Вступление
В этом уроке мы будем конвертировать поток в массив как для простых типов, так и объектов.
Stream.toArray()
Метод toArray() – это встроенный метод из класса Stream, который действительно удобно использовать при преобразовании из потока в массив. Это работает как с простыми типами, так и с объектами, хотя есть небольшая разница в использовании.
Метод возвращает новый массив, это значит, что мы будем упаковывать результаты в новый массив. Для объектов нам нужно будет указать тип, а также предоставить методу конструктор массива этого типа.
Простые типы
В Java 8 есть специальные потоки для примитивных типов: IntStream, LongStream и DoubleStream. Используем IntStream для хранения диапазона целых чисел, а затем преобразуем его в массив:
IntStream stream = IntStream.range(10, 20);
int[] array = stream.toArray();
System.out.println("Printing array ...");
for (int i = 0; i < array.length; ++i)
System.out.print(array[i] + " ");
Результат:
Printing array ...
10 11 12 13 14 15 16 17 18 19
Потоки удобны для обработки данных, поэтому вам может потребоваться выполнить предварительную обработку потока, а не массива, и в конце преобразовать его в один:
IntStream stream = IntStream.range(10, 20);
int[] array = stream.filter(x -> x%2 == 0).toArray();
System.out.println("\nPrinting even numbers ...");
for (int i = 0; i < array.length; ++i)
System.out.print(array[i] + " ");
Результат:
Printing even numbers ...
10 12 14 16 18
Объекты
Для объектов метод toArray() принимает ссылку на конструктор массива для соответствующего объекта и возвращает массив этого типа. Создадим поток строковых объектов и преобразуем его в массив:
List<String> list = new ArrayList<>();
list.add("John");
list.add("Jenny");
list.add("Martha");
Stream<String> stream = list.stream();
String[] array = stream.toArray(String[]::new);
System.out.println("Printing String array ...");
for (int i = 0; i < array.length; ++i)
System.out.println(array[i]);
Результат:
Printing String array...
John
Jenny
Martha
Примечание: Метод toArray() требует использования конструктора массива, и мы использовали ссылку на метод, чтобы указать тип String[]::new. toArray() возвращает массив указанного типа, и если тип не указан, произойдет несоответствие:
String[] array = stream.toArray();
В результате ошибка:
error: incompatible types: Object[] cannot be converted to String[]
Вместо ссылок на сокращённые методы мы можем использовать для этого лямбда-выражения. Давайте отфильтруем только имена, начинающиеся на “J”:
List<String> list = new ArrayList<>();
list.add("John");
list.add("Jenny");
list.add("Martha");
Stream<String> stream = list.stream();
String[] array = stream
.filter(string -> string.startsWith("J"))
.toArray(size -> new String[size]);
System.out.println("Printing names starting with 'J'...");
for (int i = 0; i < array.length; ++i)
System.out.println(array[i]);
Вывод:
Printing names starting with 'J'...
John
Jenny
Заключение
В этой статье мы преобразовали поток в массив. Это можно сделать для массивов и объектов с помощью метода Stream.toArray(), хотя и с несколько иным использованием.