Qual è il modo più semplice / più breve per convertire un Java 8 Stream
in un array?
Qual è il modo più semplice / più breve per convertire un Java 8 Stream
in un array?
Risposte:
Il metodo più semplice è utilizzare il toArray(IntFunction<A[]> generator)
metodo con un riferimento al costruttore di array. Questo è suggerito nella documentazione API per il metodo .
String[] stringArray = stringStream.toArray(String[]::new);
Ciò che fa è trovare un metodo che accetta un intero (la dimensione) come argomento e restituisce a String[]
, che è esattamente ciò che (uno dei sovraccarichi di) new String[]
fa.
Puoi anche scrivere il tuo IntFunction
:
Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);
Lo scopo di IntFunction<A[]> generator
è convertire un intero, la dimensione dell'array, in un nuovo array.
Codice di esempio:
Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);
stampe:
a
b
c
toArray(sz -> new String[sz])
quindi non sono sicuro che si possa davvero dire quale soluzione dovrebbe o debba essere.
sz -> new String[sz]
crea una nuova funzione, come invece il riferimento del costruttore no. Dipende da quanto apprezzi Garurn Collection Churn.
private
metodo , che non può causare churn, ed entrambe le versioni devono creare un nuovo oggetto. Un riferimento crea un oggetto che punta direttamente al metodo target; un lambda crea un oggetto che punta a quello generato private
. Un riferimento a un costruttore dovrebbe comunque funzionare meglio per mancanza di indiretta e ottimizzazione della VM più semplice, ma il churning non ha nulla a che fare con esso.
Se vuoi ottenere una matrice di ints, con valori da 1 a 10, da uno Stream, c'è IntStream a tua disposizione.
Qui creiamo uno Stream con un metodo Stream.of e convertiamo uno Stream in un IntStream usando mapToInt. Quindi possiamo chiamare il metodo toArray di 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();
Ecco la stessa cosa, senza lo Stream, usando solo IntStream
int[]array2 = IntStream.rangeClosed(1, 10).toArray();
Puoi convertire un flusso Java 8 in un array usando questo semplice blocco di codice:
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Ma spieghiamo di più le cose, in primo luogo, creiamo un elenco di stringhe riempite con tre valori:
String[] stringList = {"Bachiri","Taoufiq","Abderrahman"};
Crea uno stream dall'array specificato:
Stream<String> stringStream = Arrays.stream(stringList);
ora possiamo eseguire alcune operazioni su questo flusso Ex:
Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());
e infine convertirlo in un array Java 8 usando questi metodi:
Metodo 1-Classic (interfaccia funzionale)
IntFunction<String[]> intFunction = new IntFunction<String[]>() {
@Override
public String[] apply(int value) {
return new String[value];
}
};
String[] myNewArray = myNewStream.toArray(intFunction);
2 -Lambda espressione
String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);
3- Riferimento al metodo
String[] myNewArray3 = myNewStream.toArray(String[]::new);
Metodo di riferimento Spiegazione:
È un altro modo di scrivere un'espressione lambda che è strettamente equivalente all'altro.
Converti il testo in array di stringhe in cui separa ogni valore con una virgola e ritaglia ogni campo, ad esempio:
String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);
È possibile creare un raccoglitore personalizzato che converta un flusso in array.
public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
return Collectors.collectingAndThen(
Collectors.toList(),
list ->list.toArray( converter.apply( list.size() ) ) );
}
e un uso rapido
List<String> input = Arrays.asList( ..... );
String[] result = input.stream().
.collect( CustomCollectors.**toArray**( String[]::new ) );
Collectors.groupingBy
modo da poter mappare alcuni attributi su matrici di oggetti per valore di attributo. Questa risposta mi dà esattamente questo. Anche @DidierL.
L'uso del toArray(IntFunction<A[]> generator)
metodo è davvero un modo molto elegante e sicuro per convertire (o più correttamente, raccogliere) uno Stream in un array dello stesso tipo di Stream.
Tuttavia, se il tipo di array restituito non è importante, utilizzare semplicemente il toArray()
metodo è sia più semplice che più breve. Per esempio:
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);
}
}
}
Provalo 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]);
Puoi farlo in diversi modi. Tutti i modi sono tecnicamente uguali ma l'uso di Lambda semplificherebbe parte del codice. Diciamo che inizializziamo prima un Elenco con String, chiamandolo persone.
List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();
Ora puoi utilizzare uno dei seguenti modi.
Utilizzo di Lambda Expresiion per creare un nuovo StringArray con dimensioni definite.
String [] stringArray = stream.toArray (size-> new String [size]);
Utilizzo diretto del metodo di riferimento.
String [] stringArray = stream.toArray (String [] :: new);