Jaki jest najłatwiejszy / najkrótszy sposób na konwersję Java 8 Stream
na tablicę?
Jaki jest najłatwiejszy / najkrótszy sposób na konwersję Java 8 Stream
na tablicę?
Odpowiedzi:
Najłatwiejszą metodą jest użycie toArray(IntFunction<A[]> generator)
metody z referencją do konstruktora tablic. Jest to sugerowane w dokumentacji interfejsu API dla tej metody .
String[] stringArray = stringStream.toArray(String[]::new);
To, co robi, to znalezienie metody, która przyjmuje liczbę całkowitą (rozmiar) jako argument i zwraca a String[]
, czyli dokładnie to, co robi (jedno z przeciążeń) new String[]
.
Możesz także napisać własny IntFunction
:
Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);
Celem tego IntFunction<A[]> generator
jest przekonwertowanie liczby całkowitej, rozmiaru tablicy, na nową tablicę.
Przykładowy kod:
Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);
Wydruki:
a
b
c
toArray(sz -> new String[sz])
więc nie jestem pewien, czy naprawdę można powiedzieć, jakie rozwiązanie powinno lub musi być.
sz -> new String[sz]
wprowadza nową funkcję, w której nie ma odwołania do konstruktora. To zależy od tego, jak bardzo cenisz śmieciowanie śmieci.
private
metodę , która nie może powodować rezygnacji, i obie wersje muszą utworzyć nowy obiekt. Odwołanie tworzy obiekt, który wskazuje bezpośrednio na metodę docelową; lambda tworzy obiekt wskazujący na wygenerowany private
. Odwołanie do konstruktora powinno nadal działać lepiej ze względu na brak pośrednictwa i łatwiejszą optymalizację maszyn wirtualnych, ale ubijanie nie ma z tym nic wspólnego.
Jeśli chcesz uzyskać tablicę liczb całkowitych o wartościach od 1 do 10 ze strumienia, masz do dyspozycji IntStream.
Tutaj tworzymy strumień metodą Stream.of i konwertujemy strumień do IntStream za pomocą mapToInt. Następnie możemy wywołać metodę toArray 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();
Oto to samo, bez Strumienia, używając tylko IntStream
int[]array2 = IntStream.rangeClosed(1, 10).toArray();
Możesz przekonwertować strumień Java 8 na tablicę za pomocą tego prostego bloku kodu:
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Ale wyjaśnijmy więcej, najpierw stwórzmy listę łańcuchów wypełnionych trzema wartościami:
String[] stringList = {"Bachiri","Taoufiq","Abderrahman"};
Utwórz strumień z podanej tablicy:
Stream<String> stringStream = Arrays.stream(stringList);
możemy teraz wykonać niektóre operacje na tym strumieniu. Przykład:
Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());
i na koniec przekonwertować go na java 8 Array przy użyciu następujących metod:
Metoda 1-klasyczna (interfejs funkcjonalny)
IntFunction<String[]> intFunction = new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
};
String[] myNewArray = myNewStream.toArray(intFunction);
2-wyrażenie lambda
String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);
3- Odniesienie do metody
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Odwołanie do metody Objaśnienie:
Jest to inny sposób pisania wyrażenia lambda, który jest ściśle równoważny z drugim.
Konwertuj tekst na tablicę łańcuchów, gdzie oddzielamy każdą wartość przecinkiem, i przycinaj wszystkie pola, na przykład:
String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);
Możesz utworzyć niestandardowy moduł zbierający, który konwertuje strumień na tablicę.
public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
return Collectors.collectingAndThen(
Collectors.toList(),
list ->list.toArray( converter.apply( list.size() ) ) );
}
i szybkie użycie
List<String> input = Arrays.asList( ..... );
String[] result = input.stream().
.collect( CustomCollectors.**toArray**( String[]::new ) );
Collectors.groupingBy
aby móc mapować niektóre atrybuty na tablice obiektów według wartości atrybutu. Ta odpowiedź daje mi dokładnie to. Również @DidierL.
Używając toArray(IntFunction<A[]> generator)
metody jest w rzeczywistości bardzo eleganckim i bezpiecznym sposobem konwersji (lub, bardziej poprawnie, zbierania) Strumienia na tablicę tego samego typu Strumienia.
Jeśli jednak typ zwracanej tablicy nie jest ważny, po prostu użycie toArray()
metody jest zarówno łatwiejsze, jak i krótsze. Na przykład:
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);
}
}
}
Wypróbuj online: 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]);
Możesz to zrobić na kilka sposobów: wszystkie są technicznie takie same, ale użycie Lambdy uprościłoby część kodu. Powiedzmy, że najpierw inicjujemy Listę ciągiem, nazywamy ją osobami.
List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();
Teraz możesz użyć jednego z następujących sposobów.
Użycie Lambda Expresiion do utworzenia nowego StringArray o zdefiniowanym rozmiarze.
String [] stringArray = stream.toArray (size-> new String [size]);
Bezpośrednie użycie metody
String [] stringArray = stream.toArray (String [] :: new);