Який найпростіший / найкоротший спосіб перетворити 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
. Посилання на конструктор все-таки має краще працювати через відсутність опосередкованості та простішу оптимізацію ВМ, але збивання не має нічого спільного.
Якщо ви хочете отримати масив ints зі значеннями від 1 до 10 від Stream, у вашому розпорядженні є IntStream.
Тут ми створюємо Stream методом Stream.of і перетворюємо Stream в IntStream за допомогою mapToInt. Тоді ми можемо викликати метод IntArray toArray.
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();
Тут те саме, без Stream, використовуючи лише 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);
Тепер ми можемо виконувати деякі операції над цим потоком Ex:
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 -Lambda вираз
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)
методу - це дійсно дуже елегантний і безпечний спосіб перетворення (або правильніше зібрати) потоку в масив того ж типу Stream.
Однак якщо тип повернутого масиву не важливий, просто використовувати 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 спростить частину коду. Скажімо, ми спочатку ініціалізуємо список зі String, називаємо його особами.
List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();
Тепер ви можете скористатися одним із наступних способів.
Використання Lambda Expressionion для створення нового StringArray з визначеним розміром.
String [] stringArray = stream.toArray (size-> new String [size]);
Використання посилання безпосередньо на метод.
String [] stringArray = stream.toArray (String [] :: новий);