Come convertire un flusso Java 8 in un array?


775

Qual è il modo più semplice / più breve per convertire un Java 8 Streamin un array?


2
Ti suggerirei di ripristinare il rollback poiché la domanda era più completa e mostrava che avevi provato qualcosa.
Skiwi,

2
@skiwi Grazie! ma pensavo che il codice tentato in realtà non aggiungesse ulteriori informazioni alla domanda, e nessuno ha ancora urlato "mostraci il tuo tentativo" =)

17
@skiwi: Anche se di solito grido alle domande "fai i miei compiti" invece di me, questa particolare domanda mi sembra più chiara senza alcun disordine aggiuntivo. Teniamolo in ordine.
Honza Zidek,

Puoi trovare molte risposte e indicazioni nei documenti ufficiali del pacchetto: docs.oracle.com/javase/8/docs/api/java/util/stream/…
Christophe Roussy

Risposte:


1168

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

8
e qui è una spiegazione perché e come il costruttore di riferimento Array in realtà di lavoro: stackoverflow.com/questions/29447561/...
jarek.jpa

"Zenexer ha ragione, la soluzione dovrebbe essere: stream.toArray (String [] :: new);" ... Bene ok, ma si dovrebbe capire che il riferimento al metodo è logicamente e funzionalmente equivalente, toArray(sz -> new String[sz])quindi non sono sicuro che si possa davvero dire quale soluzione dovrebbe o debba essere.
Scott

3
@scottb sz -> new String[sz]crea una nuova funzione, come invece il riferimento del costruttore no. Dipende da quanto apprezzi Garurn Collection Churn.
WORMSS,

3
@WORMSS No. (Staticamente!) Crea un nuovo 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.
HTNW,

2
@HTNW hai ragione, mi scuso. È stato infatti il ​​mio tentativo di eseguire il debug che stava causando la zangola che stava causando la zangola la prima volta che ho provato a farlo, quindi mi è rimasto bloccato nella testa che era così. (Odialo quando succede).
WORMSS,

41

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();

16

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.


7

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);

5

È 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 ) );

5
Perché dovresti usare questo invece di Stream.toArray (IntFunction) ?
Didier L

Avevo bisogno di un raccoglitore per passare a 2-arg in Collectors.groupingBymodo da poter mappare alcuni attributi su matrici di oggetti per valore di attributo. Questa risposta mi dà esattamente questo. Anche @DidierL.
Ole VV,

3

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());

0
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

int[] arr=   stream.mapToInt(x->x.intValue()).toArray();

0
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


Qual è la differenza tra la tua risposta e la risposta accettata?
Long Nguyen,

@LongNguyen È un esempio completo che include uno scenario di riproduzione online, non solo uno snippet.
Sma Ma,

-1
     Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

     Integer[] integers = stream.toArray(it->new Integer[it]);

-2

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.

  1. Utilizzo di Lambda Expresiion per creare un nuovo StringArray con dimensioni definite.

    String [] stringArray = stream.toArray (size-> new String [size]);

  2. Utilizzo diretto del metodo di riferimento.

    String [] stringArray = stream.toArray (String [] :: new);

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.