[java8] Um die Stream-API zu verstehen

Es ist 4 Monate her, seit ich meinen Job zu einem Ingenieur ohne Erfahrung gewechselt habe und dem Java-Team zugewiesen wurde. Ich bin bereits an Java gewöhnt, verwende aber die erweiterte for-Anweisung, um die Liste zu erweitern. Ich möchte mit der Stream-API auskommen, also habe ich sie zusammengefasst.

Wir planen, nach Bedarf Methoden hinzuzufügen.

Was ist die Stream-API?

Überblick

Als Ausgangspunkt finde ich es gut, einen Eindruck von "** etwas zu haben, mit dem Sie das Array einfach bedienen können **". Die Verzögerungsauswertung und die asynchrone Verarbeitung werden im Folgenden beschrieben, müssen jedoch zunächst nicht bekannt sein. (Ich verstehe nicht viel, also möchte ich das denken ..)

API-Funktionen streamen

Stream kann Arrays mit einer geringen Menge an Beschreibung betreiben und verfügt über die folgenden Funktionen.

Asynchrone Verarbeitung

Die Stream-API kann die asynchrone Verarbeitung durchführen. Bei der asynchronen Verarbeitung werden, wie der Name schon sagt, eine Reihe von Prozessen nicht nacheinander ausgeführt (synchronisiert), sondern parallel ausgeführt (asynchron). Verwenden Sie für die asynchrone Verarbeitung mit der Stream-API list.parallelStream () oder List.stream (). Parallel () anstelle der üblichen List.stream ().

Wenn beispielsweise ein Prozess zum Ausgeben der folgenden Listenelemente auf dem Bildschirm vorhanden ist,

List<Integer> demoList = Arrays.asList(1, 2, 3, 4, 5);

Wenn Sie dies synchron tun, erfolgt die Ausgabe in der Reihenfolge des Arrays, da sie nacheinander ausgeführt wird.

    for(Integer i : demoList) {
      System.out.print(i);
    }
    // 12345

Wenn Sie dies jedoch asynchron tun, wird es parallel verarbeitet, sodass sich die Ausgabe von der Reihenfolge des Arrays unterscheidet.

    demoList.stream().parallel().forEach(System.out::print);
    // 32415

Durch Ausführen einer asynchronen Verarbeitung kann die Verarbeitung auch schneller ausgeführt werden als das Drehen der Liste mit For. Ich habe tatsächlich die Zeit gemessen.


    //Zielliste
    List<Integer> demoList = Stream.iterate(1, n -> n + 1).limit(100000).collect(Collectors.toList());

    //Für Holen Sie sich die Zeit vor der Verarbeitung
    long startTimeFor = System.currentTimeMillis();

    //Ausgabe mit For
    for(Integer i : demoList) {
      System.out.println(i);;
    }

    //Holen Sie sich die Zeit nach Für die Verarbeitung
    long endTimeFor = System.currentTimeMillis();

    //Holen Sie sich die Zeit vor der Stream-Verarbeitung
    long startTimeStream = System.currentTimeMillis();
    
    //Ausgabe mit Stream
    demoList.parallelStream().forEach(System.out::println);

    //Holen Sie sich die Zeit nach der Stream-Verarbeitung
    long endTimeStream = System.currentTimeMillis();

    System.out.println("Bearbeitungszeit Für:" + (endTimeFor - startTimeFor) + " ms");
    System.out.println("Bearbeitungszeit Stream:" + (endTimeStream - startTimeStream) + " ms");

Die Ergebnisse sind wie folgt. Es ist nicht so unterschiedlich wie ich erwartet hatte, aber der obige Prozess war im Durchschnitt etwa 100 ms schneller.

Bearbeitungszeit Für: 686 ms
Bearbeitungszeit Stream: 573 ms

Verzögerungsauswertung

Die Stream-API kann eine Verzögerungsbewertung von Funktionssprachen durchführen. Was ist eine Verzögerungsbewertung?

Bei der Programmierung werden Formeln häufig berechnet, wenn sie angezeigt werden. Bei der Verzögerungsbewertung werden sie jedoch erst berechnet, wenn sie tatsächlich benötigt werden.

Es ist. In StreamAPI werden Ausdrücke während der später beschriebenen Zwischenoperationen (Zuordnung und Filter) nicht ausgewertet. Es wird nur ausgewertet, wenn die Beendigungsoperation ausgeführt wird. Verschieben wir es tatsächlich und überprüfen es.

    //Zielliste
    List<Integer> demoList = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));

    //Es werden nur gerade Zahlen gestreamt. Da es sich um einen Zwischenprozess handelt, wurde er noch nicht ausgewertet.
    Stream<Integer> oddListStream = demoList.stream().filter(n -> n % 2 == 0);

    //Element zur Demoliste hinzufügen
    demoList.add(6);
    demoList.add(7);
    demoList.add(8);

    //Ausgabestrom
    oddListStream.forEach(System.out::print);

Wenn Sie normal darüber nachdenken, sollte der oddListStream, der den Stream generiert, 2 und 4 enthalten. Die Zwischenoperationen von Stream werden jedoch verzögert ausgewertet und erst ausgewertet, wenn die Beendigungsoperation für jede aufgerufen wird. Die Ausgabe ist also ...

$  2468

Und 6,7,8 wurden der DemoList hinzugefügt, nachdem die Stream-Generierung verarbeitet wurde.

Prozessablauf

Von hier aus betrachten wir die Stream-Operation in der Reihenfolge Generierung → Zwischenoperation → Beendigungsoperation.

1. Stream-Generierung

Erstellen Sie zunächst einen Stream, der die Grundlage für die Ausführung der unten beschriebenen Vorgänge bildet. Zusätzlich zu dem häufig verwendeten List.stream () verfügt Stream über verschiedene Methoden, z. B. die Verwendung eines Konstruktors und eines Builders.

    //Vom Listentyp
    Stream<Integer> numberStreamFromList = Arrays.asList(8, 1, 4, 2, 9).stream();

    // Stream.mit von
    Stream<Integer> numberStreamFromStreamOf = Stream.of(8, 1, 4, 2, 9);

    //Builder verwenden
    Builder<String> builder = Stream.builder();
    Stream<String> stringStream = builder.add("hoge").add("fuga").build();

    //Leerer Stream
    Stream<String> emptyStream = Stream.empty();

    //Mit iterieren
    Stream<Integer> numberStreamFromIterate = Stream.iterate(1, n -> n * 10).limit(5);

Nur die Methode der Iteration ist etwas schwer zu verstehen, daher handelt es sich um eine Ergänzung. Die grundlegende Syntax lautet wie folgt.

Stream.iterate(Ursprünglicher Wert, Ursprünglicher Wertが入る変数 ->Verarbeitung für Variablen).limit(Anzahl der Wiederholungen)

Der Grund für die Anwendung von Limit ist, dass Limit, wenn es nicht verwendet wird, auf unbestimmte Zeit generiert wird.

Sie können diese Ausgabe einfach mit iterate ausführen.

Sagen Sie eine Zahl von 1 und werden Sie nur dann dumm, wenn es ein Vielfaches von 3 ist (fühlen Sie die Zeiten ..)

    Stream.iterate(1, n -> n + 1).limit(100)
        .map(n -> n % 3 == 0 ? "Blöd" : n)
        .forEach(System.out::println);

2. Zwischenbetrieb

Die Zwischenoperation besteht darin, eine Verarbeitung wie das Filtern und Ausführen von Funktionen für jedes Element des Arrays durchzuführen. Die Zwischenoperation kann viele Male wiederholt werden. Nach dem Filtern mit Karte usw. verarbeiten. Bitte beachten Sie, dass der Rückgabewert der Zwischenoperation vom Typ stream ist. Es gibt kein Array in list.map wie Ruby zurück. Um es anders als den Stream -Typ zu machen, ist die später beschriebene Beendigungsoperation erforderlich.

Elementauswahl [Filter]

Sie können Elemente unter bestimmten Bedingungen mit filter () * filtern *. Das Folgende ist ein Verwendungsbeispiel.

Geben Sie nur gerade Zahlen aus dem Array aus

    //Zielliste
    List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);

    //Ausgabe nur für Anweisung
    for (Integer number : numberList) {
      if (number % 2 == 0) {
        System.out.println(number);
      }
    }

    //Nur geraden Stream ausgeben
    numberList.stream()
        .filter(n -> n % 2 == 0)
        .forEach(System.out::println);

Element bearbeiten [Karte]

Verdoppelt jedes Element des Arrays und gibt es aus

    List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);

    //Ausgabe durch Verdoppeln jedes Elements für die Anweisung
    for (Integer number : numberList) {
      System.out.println(number * 2);
    }

    //Verdoppeln Sie jedes Element für den Ausgabestream
    numberList.stream()
        .map(n -> n * 2)
        .forEach(System.out::println);

Elemente sortieren [sortieren]

Das Sortieren von Elementen ist mit Sortieren einfach.

    List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);

    List<Integer> sortListAsc = numberList.stream().sorted().collect(Collectors.toList());

    List<Integer> sortListDesc = numberList.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());

    System.out.println(sortListAsc);
    // [1, 2, 4, 8, 9]

    System.out.println(sortListDesc);
    // [9, 8, 4, 2, 1]

3. Kündigungsoperation

Für die Beendigungsoperation können Sie die Funktion nacheinander mit dem von map, filter usw. verarbeiteten Stream ausführen oder in den angegebenen Typ konvertieren. Der Unterschied zur Zwischenoperation besteht darin, dass der Rückgabewert nicht Stream ist.

Das Folgende ist ein typisches Beispiel.

Erhalten Sie das Ergebnis in der angegebenen Art [sammeln]

Mit collect können Sie einen Stream in verschiedene Typen konvertieren und das Ergebnis abrufen.

Als Array empfangen [Collectors.toList ()]

Verdoppeln Sie das Element und erhalten Sie das Ergebnis als Array

    List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);

    List<Integer> doubleList = numberList.stream()
        .map(n -> n * 2)
        .collect(Collectors.toList());

    System.out.println(doubleList); //[16, 2, 8, 4, 18]

Auf Karte empfangen [Collectors.toMap ()]

Beurteilen Sie den Wert und erstellen Sie eine Karte mit dem Namen [Wert, "gerade" oder "ungerade"].

    List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);

    Map<Integer, String> demoMap  = numberList.stream()
        .collect(Collectors.toMap(
            n -> n,
            s -> s % 2 == 0 ? "Sogar" : "Seltsam"));

    System.out.println(demoMap); //{1=Seltsam, 2=Sogar, 4=Sogar, 8=Sogar, 9=Seltsam}

Verarbeite jedes Element [für jedes]

Standardausgabe wie sie ist

    List<Integer> numberList = Arrays.asList(8, 1, 4, 2, 9);

    //Beide sind gleich
    numberList.stream().forEach(n -> System.out.println(n));
    numberList.stream().forEach(System.out::println);

Referenz

http://www.task-notes.com/entry/20150518/1431918000 https://qiita.com/nmby/items/52d1b0e2dad5df475737 http://aoking.hatenablog.jp/entry/20110810/1312970979 https://qiita.com/kumazo/items/104fa685da8705b8cfd8#36-flatmap

Recommended Posts

[java8] Um die Stream-API zu verstehen
[Java] Einführung in die Stream-API
[Einführung in Java] Informationen zur Stream-API
Java Stream API
Java 8 ~ Stream API ~ startet jetzt
Java-Referenz zum Verständnis in der Abbildung
Versuchen Sie es mit der Stream-API in Java
Ich habe versucht, die Stream-API zusammenzufassen
[Java] Stream API / Map
Java Stream API Spickzettel
Java Stream API in 5 Minuten
[Java] Stream API - Stream-Beendigungsverarbeitung
[Java] Stream API - Stream Zwischenverarbeitung
Java-Thread locker zu verstehen
[Java] Stream API Zwischenoperation
Eingabe in die Java-Konsole
[Für Anfänger] So bedienen Sie die Stream-API nach Java 8
Verwenden Sie Java-Lambda-Ausdrücke außerhalb der Stream-API
In der Abbildung verstandene Java-Klassen und -Instanzen
Java: Verwenden Sie Stream, um den Inhalt einer Sammlung zu sortieren
[Ein Muss für einen Java-Ingenieurlehrling] Verwendung der Stream-API
Ich möchte die Java 8 DateTime-API (jetzt) langsam verwenden.
Ich habe versucht, die Java8 Stream API zu verwenden
Willkommen im Sumpf der Java-Bibliotheken! !!
Analysieren der COTOHA-API-Syntaxanalyse in Java
Listenverarbeitung zum Verstehen mit Bildern --java8 stream / javaslang --bonus
Jetzt ist es an der Zeit, mit der Stream-API zu beginnen
Der Weg von JavaScript nach Java
Konvertieren Sie ein zweidimensionales Array mit der Java 8 Stream-API in das CSV-Format
So spielen Sie eine MIDI-Datei mit der Java Sound API ab
Beispielcode zum Aufrufen der Yahoo! Local Search API in Java
Nutzen Sie entweder für die individuelle Ausnahmebehandlung in der Java Stream-API
[Java] Verwendung der File-Klasse
Datenverarbeitung mit der Stream-API von Java 8
Einführung in Java zum ersten Mal # 2
Rufen Sie die Windows-Benachrichtigungs-API in Java auf
Java SE8 Silber ~ Der Weg zum Pass ~
Heutzutage Java Lambda Expressions und Stream API
Über das Verfahren, damit Java funktioniert
[Java] Verwendung der toString () -Methode
Rufen Sie die Salesforce REST-API von Java aus auf
Studieren der Verwendung des Konstruktors (Java)
[Verarbeitung × Java] Verwendung der Schleife
[Java] So stellen Sie die Datums- und Uhrzeit auf 00:00:00 ein
Probieren Sie verschiedene Java Stream API-Methoden aus (jetzt)
[Java] So erhalten Sie das aktuelle Verzeichnis
Java 8 startet jetzt ~ Datums- und Uhrzeit-API ~
[Java] Map # Merge ist schwer zu verstehen.
Die Java EE Security API ist da!
[Verarbeitung × Java] Verwendung der Klasse
Anonyme Klasse (mit dem Ziel, Stream-API einzuführen)
So erhalten Sie das Datum mit Java
Ausgabe des Buches "Einführung in Java"
[Verarbeitung × Java] Verwendung der Funktion
Ich ging zum Java Women's Club # 1