Какой самый простой / короткий способ конвертировать Java 8 Stream
в массив?
Какой самый простой / короткий способ конвертировать Java 8 Stream
в массив?
Ответы:
Самый простой способ - использовать toArray(IntFunction<A[]> generator)
метод со ссылкой на конструктор массива. Это предлагается в документации API для метода .
String[] stringArray = stringStream.toArray(String[]::new);
Что он делает, так это находит метод, который принимает целое число (размер) в качестве аргумента и возвращает a String[]
, что и делает (одна из перегрузок) new String[]
.
Вы также можете написать свой собственный IntFunction
:
Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);
Цель IntFunction<A[]> generator
- преобразовать целое число, размер массива, в новый массив.
Пример кода:
Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);
Печать:
a
b
c
toArray(sz -> new String[sz])
так что я не уверен, что кто-то действительно может сказать, какое решение должно или должно быть.
sz -> new String[sz]
создает новую функцию, а ссылка на конструктор - нет. Я думаю, это зависит от того, насколько ты ценишь отток мусора.
private
метод , который не может вызвать отток, и обе версии должны создать новый объект. Ссылка создает объект, который указывает непосредственно на целевой метод; лямбда создает объект, который указывает на сгенерированный private
. Ссылка на конструктор все равно должна работать лучше из-за отсутствия косвенности и более легкой оптимизации виртуальной машины, но отток не имеет к этому никакого отношения.
Если вы хотите получить массив потоков со значениями от 1 до 10 из потока, в вашем распоряжении есть IntStream.
Здесь мы создаем Stream с помощью метода Stream.of и конвертируем Stream в IntStream, используя mapToInt. Затем мы можем вызвать метод toStray от IntStream.
Stream<Integer> stream = Stream.of(1,2,3,4,5,6,7,8,9,10);
//or use this to create our stream
//Stream<Integer> stream = IntStream.rangeClosed(1, 10).boxed();
int[] array = stream.mapToInt(x -> x).toArray();
Здесь то же самое, без потока, используя только IntStream
int[]array2 = IntStream.rangeClosed(1, 10).toArray();
Вы можете преобразовать поток Java 8 в массив, используя этот простой блок кода:
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Но давайте объясним подробнее, во-первых, давайте создадим список строк, заполненный тремя значениями:
String[] stringList = {"Bachiri","Taoufiq","Abderrahman"};
Создайте поток из данного массива:
Stream<String> stringStream = Arrays.stream(stringList);
Теперь мы можем выполнить некоторые операции с этим потоком. Например:
Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());
и, наконец, преобразовать его в массив Java 8, используя эти методы:
1-классический метод (функциональный интерфейс)
IntFunction<String[]> intFunction = new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
};
String[] myNewArray = myNewStream.toArray(intFunction);
2-лямбда-выражение
String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);
3- Ссылка на метод
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Ссылка на метод Объяснение:
Это еще один способ написания лямбда-выражения, которое строго эквивалентно другому.
Преобразовать текст в строковый массив, где каждое значение разделяется запятой, и обрезать каждое поле, например:
String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);
Вы можете создать собственный коллектор, который преобразует поток в массив.
public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
return Collectors.collectingAndThen(
Collectors.toList(),
list ->list.toArray( converter.apply( list.size() ) ) );
}
и быстрое использование
List<String> input = Arrays.asList( ..... );
String[] result = input.stream().
.collect( CustomCollectors.**toArray**( String[]::new ) );
Collectors.groupingBy
чтобы я мог сопоставить некоторый атрибут с массивами объектов по значению атрибута. Этот ответ дает мне именно это. Также @DidierL.
Использование toArray(IntFunction<A[]> generator)
метода действительно является очень элегантным и безопасным способом преобразования (или, точнее, сбора) потока в массив того же типа, что и поток.
Однако, если тип возвращаемого массива не важен, простое использование toArray()
метода и проще, и короче. Например:
Stream<Object> args = Stream.of(BigDecimal.ONE, "Two", 3);
System.out.printf("%s, %s, %s!", args.toArray());
import java.util.List;
import java.util.stream.Stream;
class Main {
public static void main(String[] args) {
// Create a stream of strings from list of strings
Stream<String> myStreamOfStrings = List.of("lala", "foo", "bar").stream();
// Convert stream to array by using toArray method
String[] myArrayOfStrings = myStreamOfStrings.toArray(String[]::new);
// Print results
for (String string : myArrayOfStrings) {
System.out.println(string);
}
}
}
Попробуйте это онлайн: https://repl.it/@SmaMa/Stream-to-array
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);
Integer[] integers = stream.toArray(it->new Integer[it]);
Вы можете сделать это несколькими способами. Все способы технически одинаковы, но использование Lambda упростит часть кода. Допустим, мы сначала инициализируем List с помощью String, назовем его person.
List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();
Теперь вы можете использовать любой из следующих способов.
Использование Lambda Expresiion для создания нового StringArray с определенным размером.
String [] stringArray = stream.toArray (size-> new String [size]);
Используя ссылку на метод напрямую.
String [] stringArray = stream.toArray (String [] :: new);