Wie konvertiere ich einen Java 8 Stream in ein Array?


775

Was ist der einfachste / kürzeste Weg, um Java 8 Streamin ein Array zu konvertieren ?


2
Ich würde Ihnen vorschlagen, den Rollback zurückzusetzen, da die Frage vollständiger war und zeigte, dass Sie etwas versucht hatten.
Skiwi

2
@skiwi Danke! aber ich dachte, der versuchte Code fügt der Frage nicht wirklich mehr Informationen hinzu, und noch hat niemand geschrien "Zeig uns deinen Versuch" =)

17
@skiwi: Obwohl ich normalerweise die Hausaufgaben anstelle von mir anschreie, scheint mir diese spezielle Frage ohne zusätzliches Durcheinander klarer zu sein. Lass es uns ordentlich halten.
Honza Zidek

Viele Antworten und Anleitungen finden Sie in den offiziellen Dokumenten des Pakets: docs.oracle.com/javase/8/docs/api/java/util/stream/…
Christophe Roussy

Antworten:


1168

Die einfachste Methode besteht darin, die toArray(IntFunction<A[]> generator)Methode mit einer Array-Konstruktorreferenz zu verwenden. Dies wird in der API-Dokumentation für die Methode vorgeschlagen .

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

Es wird eine Methode gefunden, die eine Ganzzahl (die Größe) als Argument verwendet und a zurückgibt String[], was genau das ist, was (eine der Überladungen von) new String[]tut.

Sie können auch Ihre eigenen schreiben IntFunction:

Stream<String> stringStream = ...;
String[] stringArray = stringStream.toArray(size -> new String[size]);

Der Zweck von IntFunction<A[]> generatorist das Konvertieren einer Ganzzahl, der Größe des Arrays, in ein neues Array.

Beispielcode:

Stream<String> stringStream = Stream.of("a", "b", "c");
String[] stringArray = stringStream.toArray(size -> new String[size]);
Arrays.stream(stringArray).forEach(System.out::println);

Drucke:

a
b
c

8
und hier ist eine Erklärung, warum und wie die Array-Konstruktorreferenz tatsächlich funktioniert: stackoverflow.com/questions/29447561/…
jarek.jpa

"Zenexer hat recht, die Lösung sollte lauten: stream.toArray (String [] :: new);" ... Na gut, aber man sollte verstehen, dass die Methodenreferenz logisch und funktional äquivalent ist, toArray(sz -> new String[sz])also bin ich mir nicht sicher, ob man wirklich sagen kann, was die Lösung sein sollte oder muss.
Scottb

3
@scottb sz -> new String[sz]macht eine neue Funktion, wo dies als Konstruktorreferenz nicht der Fall ist. Es hängt davon ab, wie sehr Sie Garbage Collection Churn schätzen, denke ich.
WORMSS

3
@WORMSS Das tut es nicht. Es erstellt (statisch!) Eine neue private Methode , die keine Abwanderung verursachen kann, und beide Versionen müssen ein neues Objekt erstellen. Eine Referenz erstellt ein Objekt, das direkt auf die Zielmethode zeigt. Ein Lambda erstellt ein Objekt, das auf das generierte zeigt private. Ein Verweis auf einen Konstruktor sollte aufgrund mangelnder Indirektion und einfacherer VM-Optimierung immer noch eine bessere Leistung erbringen, aber Churning hat nichts damit zu tun.
HTNW

2
@HTNW du bist richtig, ich entschuldige mich. Es war genau mein Versuch zu debuggen, der die Abwanderung verursachte, die die Abwanderung verursachte, als ich das erste Mal versuchte, dies zu tun, also hatte ich es im Kopf, dass es so war. (Hasse es, wenn das passiert).
WORMSS

41

Wenn Sie ein Array von Ints mit den Werten 1 bis 10 aus einem Stream abrufen möchten, steht Ihnen IntStream zur Verfügung.

Hier erstellen wir einen Stream mit einer Stream.of-Methode und konvertieren einen Stream mithilfe von mapToInt in einen IntStream. Dann können wir die toArray-Methode von IntStream aufrufen.

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

Hier ist das Gleiche ohne den Stream, der nur den IntStream verwendet

int[]array2 =  IntStream.rangeClosed(1, 10).toArray();

15

Mit diesem einfachen Codeblock können Sie einen Java 8-Stream in ein Array konvertieren:

 String[] myNewArray3 = myNewStream.toArray(String[]::new);

Aber lassen Sie uns die Dinge näher erläutern. Lassen Sie uns zunächst eine Liste von Zeichenfolgen erstellen, die mit drei Werten gefüllt sind:

String[] stringList = {"Bachiri","Taoufiq","Abderrahman"};

Erstellen Sie einen Stream aus dem angegebenen Array:

Stream<String> stringStream = Arrays.stream(stringList);

Wir können jetzt einige Operationen an diesem Stream ausführen.

Stream<String> myNewStream = stringStream.map(s -> s.toUpperCase());

und konvertieren Sie es schließlich mit den folgenden Methoden in ein Java 8-Array:

1-Klassische Methode (Funktionsschnittstelle)

IntFunction<String[]> intFunction = new IntFunction<String[]>() {
    @Override
    public String[] apply(int value) {
        return new String[value];
    }
};


String[] myNewArray = myNewStream.toArray(intFunction);

2-Lambda-Ausdruck

 String[] myNewArray2 = myNewStream.toArray(value -> new String[value]);

3- Methodenreferenz

String[] myNewArray3 = myNewStream.toArray(String[]::new);

Methodenreferenz Erläuterung:

Es ist eine andere Art, einen Lambda-Ausdruck zu schreiben, der dem anderen genau entspricht.


6

Konvertieren Sie Text in ein Zeichenfolgenarray, in dem jeder Wert durch Komma getrennt wird, und schneiden Sie jedes Feld ab. Beispiel:

String[] stringArray = Arrays.stream(line.split(",")).map(String::trim).toArray(String[]::new);

4

Sie können einen benutzerdefinierten Kollektor erstellen, der einen Stream in ein Array konvertiert.

public static <T> Collector<T, ?, T[]> toArray( IntFunction<T[]> converter )
{
    return Collectors.collectingAndThen( 
                  Collectors.toList(), 
                  list ->list.toArray( converter.apply( list.size() ) ) );
}

und eine schnelle Verwendung

List<String> input = Arrays.asList( ..... );

String[] result = input.stream().
         .collect( CustomCollectors.**toArray**( String[]::new ) );

5
Warum sollten Sie dies anstelle von Stream.toArray (IntFunction) verwenden ?
Didier L

Ich brauchte einen Kollektor, um an das 2-Argument zu übergeben, Collectors.groupingBydamit ich Arrays von Objekten pro Attributwert ein Attribut zuordnen konnte. Diese Antwort gibt mir genau das. Auch @DidierL.
Ole VV

3

Die Verwendung der toArray(IntFunction<A[]> generator)Methode ist in der Tat eine sehr elegante und sichere Methode, um einen Stream in ein Array des gleichen Stream-Typs zu konvertieren (oder genauer gesagt zu sammeln).

Wenn der Typ des zurückgegebenen Arrays jedoch nicht wichtig ist, ist die einfache Verwendung der toArray()Methode sowohl einfacher als auch kürzer. Zum Beispiel:

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

Probieren Sie es online aus: https://repl.it/@SmaMa/Stream-to-array


Was ist der Unterschied zwischen Ihrer Antwort und der akzeptierten Antwort?
Long Nguyen

@LongNguyen Es ist ein vollständiges Beispiel, das ein Online-Wiedergabeszenario enthält, nicht nur ein Snippet.
Sma Ma

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

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

-2

Sie können dies auf verschiedene Arten tun. Alle Möglichkeiten sind technisch gleich, aber die Verwendung von Lambda würde einen Teil des Codes vereinfachen. Nehmen wir an, wir initialisieren eine Liste zuerst mit String und nennen sie Personen.

List<String> persons = new ArrayList<String>(){{add("a"); add("b"); add("c");}};
Stream<String> stream = persons.stream();

Jetzt können Sie eine der folgenden Möglichkeiten verwenden.

  1. Verwenden des Lambda-Ausdrucks zum Erstellen eines neuen StringArray mit definierter Größe.

    String [] stringArray = stream.toArray (Größe-> neuer String [Größe]);

  2. Verwenden Sie die Methodenreferenz direkt.

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.