Stream-API

Veröffentlicht in der Gruppe Random-DE
Stream-API – 1

Was ist die Stream-API?

Die Stream-API ist eine neue Möglichkeit, mit Datenstrukturen in einem funktionalen Stil zu arbeiten. Eine Stream-API (eine Beschreibung der Art und Weise, wie ein Computerprogramm mit einem anderen Programm kommunizieren kann) ist im Kern ein Datenstrom. Der Begriff „Thread“ selbst ist in der Programmierung im Allgemeinen und in Java im Besonderen recht vage.
Stream-API – 1
Mit dem Aufkommen von Java 8 ermöglichte die Stream-API Programmierern, viel kürzer zu schreiben, was zuvor viele Codezeilen erforderte, nämlich die Arbeit mit Datensätzen zu vereinfachen, insbesondere das Filtern, Sortieren und andere Datenmanipulationsvorgänge zu vereinfachen. Wenn Sie keine Zwischenoperationen haben, können und sollten Sie oft auf einen Stream verzichten, da der Code sonst komplizierter wird als ohne Stream.
Stream-API – 2
Wo genau soll ich anfangen? Von der Erstellung einer Stream-Instanz, die auf der von uns benötigten Sammlung, dem Array oder der Methode basiert und aus der die Daten entsprechend entnommen werden:
List<String> list = new ArrayList<String>();
       list.add("One");
       list.add("Two");
       list.add("Three");
       list.add("Four");
       list.add("Five");
       list.add("Six");
       list.add("Seven");
       list.add("Eight");
       list.add("Nine");
       list.add("Ten");
       Stream stream = list.stream();
Wie oben erwähnt, können Sie mit der Stream-API die Anzahl der Codezeilen reduzieren. Beispiel mit einem Stream:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
Beispiel ohne Thread:
int[] arr = {50, 60, 70, 80, 90, 100, 110, 120
	int count = 0;
	for (int x : arr) {
	    if (x >= 90) continue;
	    x += 10;
	    count++;
	    if (count > 3) break;
	    System.out.print(x);
	}
Mögliche Möglichkeiten, einen Stream zu erstellen:
Stream-API – 3
  • Leerer Stream:Stream.empty()
  • Stream aus Liste:list.stream()
  • Von der Karte streamen:map.entrySet().stream()
  • Stream vom Array:Arrays.stream(array)
  • Stream von den angegebenen Elementen:Stream.of("1", "2", "3")
Darüber hinaus gibt es so etwas wie Operatoren (im Wesentlichen Methoden der Stream-Klasse). Operatoren können in zwei Gruppen unterteilt werden:
  • Mittelstufe (auch „faul“ genannt) – verarbeitet eingehende Elemente und gibt den Stream zurück. In der Elementverarbeitungskette kann es viele Zwischenoperatoren geben.
  • Terminal („Terminal“, auch „Eager“ genannt) – verarbeitet Elemente und beendet den Stream, sodass es nur einen Terminaloperator in der Kette geben kann.
Beispiel:
1.List<String> list = new ArrayList<String>();
2.list.add("One");11.list.add("Ten");
12.Stream stream = list.stream();
13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println);
Was ist denn hier los:
  • 1 – eine Liste erstellen list;
  • 2-11 - Füllen Sie es mit Testdaten;
  • 12 – ein Objekt erstellen Stream;
  • 13 – Methode filter(Filter) – Zwischenoperator, xwird einem Element der Sammlung zur Aufzählung gleichgesetzt (wie bei for each) und nach -> geben wir an, wie unsere Sammlung gefiltert wird, und da es sich um einen Zwischenoperator handelt, geht die gefilterte Sammlung weiter zum Methode, forEachdie wiederum das terminale (endgültige) Analogon der Aufzählung ist for each(Ausdruck System.out::printlnkurz für:, x-> System.out.println(x))der wiederum alle Elemente der an ihn übergebenen Sammlung durchgeht und diese anzeigt)
Stream-API – 5
Wichtige Punkte:
  • Die Verarbeitung beginnt erst, wenn der Terminalbetreiber aufgerufen wird. list.stream().filter(s -> s > 5)(übernimmt kein einziges Element aus der Liste);
  • Eine Instanz eines Streams kann nicht mehr als einmal verwendet werden =( ;
  • Stream-API – 6

    Deshalb jedes Mal, wenn es neu ist:

    list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
    list.stream().forEach(x -> System.out.println(x));
  • In einem Stream können viele Zwischenoperatoren aufgerufen werden, während es nur einen Terminaloperator gibt:

    stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
Schauen wir uns als Nächstes einige Zwischenoperatoren an:
Stream-API – 7
  • filter(Predicate predicate)filtert den Stream und übergibt nur die Elemente, die die Bedingung erfüllen (Predicate ist eine integrierte Funktionsschnittstelle, die dem Paket in Java SE 8 hinzugefügt wurde. java.util.functionÜberprüft den Wert auf „ true “ und „ false “);
  • map(Function mapper)ermöglicht es, eine Funktion zu erstellen, mit der wir jedes Element ändern und weiter überspringen (Die funktionale Schnittstelle Function<T,R>stellt die Funktion des Übergangs von einem Objekt vom Typ T zu einem Objekt vom Typ R dar)
  • flatMap(Function<T, Stream<R>> mapper)- Wie im Fall von mapwerden sie zur Konvertierung in einen primitiven Stream verwendet.
Wenn Sie beispielsweise mit einem Array von Streams (Arrays, Listen usw.) arbeiten, werden diese in einen Stream (Array, Liste usw.) konvertiert [stream1,stream2,stream3,stream4] => stream:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Konvertieren Sie das Wort in ein Array aus Buchstaben
        .flatMap(Arrays::stream).distinct() //richtet jeden generierten Thread zu einem einzelnen Thread aus
        .collect(Collectors.toList()).forEach(System.out::println);
Während mapes in eine Liste von Threads (genauer gesagt <Stream>Threads) konvertiert wird [stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4):
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Konvertieren Sie das Wort in ein Array aus Buchstaben
        .map(Arrays::stream).distinct() //Das Array in einen separaten Thread umwandeln
        .collect(Collectors.toList()).forEach(System.out::println);
Ein weiterer Unterschied zu map: Sie können ein Element in null, eins oder viele andere umwandeln. Um ein Element in null Elemente umzuwandeln, müssen Sie nulloder einen leeren Stream zurückgeben. Um in ein Element zu konvertieren, müssen Sie einen Stream von einem Element zurückgeben, beispielsweise über Stream.of(x). Um mehrere Elemente zurückzugeben, können Sie auf beliebige Weise einen Stream mit diesen Elementen erstellen. Die gleiche flatMap-Methode, aber für Double, Integer und Long:
  • flatMapToDouble(Funktionsmapper)
  • flatMapToInt(Funktionsmapper)
  • flatMapToLong(Funktionsmapper)
Und noch ein Vergleichsbeispiel, flatMap:
Stream.of(2, 3, 0, 1, 3)
        .flatMapToInt(x -> IntStream.range(0, x))
        .forEach(System.out::print);// 010120012
  • IntStream.range(0,x) – gibt Elemente von 0 (einschließlich) bis x (nicht einschließlich) an den Stream aus;

    Karte:

    Stream.of(2, 3, 0, 1, 3)
            .map(x -> IntStream.range(0, x))
            .forEach(System.out::print);//Liste der Streams (Streams);
  • limit(long maxSize) – begrenzt den Stream um die Anzahl der Elemente:

    stream.limit(5).forEach(x -> System.out.println(x));
  • skip(long n) – n Elemente überspringen:

    stream.skip(3).forEach(x -> System.out.println(x));
  • sortiert()

  • sorted(Comparator comparator) – sortiert den Stream (Sortierung wie TreeMap):

    stream.sorted().forEach(x -> System.out.println(x));
  • „distinct()“ – prüft den Stream auf Eindeutigkeit von Elementen (entfernt Wiederholungen von Elementen);

  • dropWhile(Predicate predicate) – überspringt Elemente, die die Bedingung erfüllen (erscheint in Java 9). Die Funktionsschnittstelle Predicate<T> prüft, ob eine bestimmte Bedingung erfüllt ist. Wenn sie erfüllt ist, wird true zurückgegeben. Der Lambda-Ausdruck akzeptiert ein Objekt von Geben Sie T als Parameter ein:

    Predicate<Integer> isPositive = x -> x > 0;
           System.out.println(isPositive.test(3)); // true
           System.out.println(isPositive.test(-9)); // false
Terminalbetreiber:
Stream-API – 8
  • forEach(Consumer action) – analog zu for every (Consumer<T> führt eine Aktion für ein Objekt vom Typ T aus, ohne etwas zurückzugeben);

  • count() – gibt die Anzahl der Stream-Elemente zurück:

    System.out.println(stream.count());

  • Collect(Collector Collector) – Methode sammelt alle Elemente in einer Liste, einem Set oder einer anderen Sammlung, gruppiert Elemente nach einem bestimmten Kriterium, kombiniert alles in einer Zeichenfolge usw.:

    List<String> list = Stream.of(One,Two,Three).collect(Collectors.toList());
  • collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)— das Gleiche wie , collect(collector)nur die Parameter werden der Einfachheit halber aufgeschlüsselt ( supplierstellt beispielsweise neue Objekte (Container) bereit, new ArrayList()fügt accumulatordem Container ein Element hinzu, combinerkombiniert Teile des Streams miteinander);

  • reduce(T-Identität, BinaryOperator-Akkumulator) – wandelt alle Elemente des Streams in ein Objekt um (berechnet die Summe aller Elemente oder findet das minimale Element), zuerst werden das Objekt identityund das erste Element des Streams genommen, die Funktion wird angewendet accumulatorund identitysein Ergebnis wird. Dann geht alles mit den restlichen Elementen weiter.

    int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
  • reduce(BinaryOperator accumulator)– die gleiche Methode wie oben, aber die erste Methode fehlt identity, es ist das erste Element des Streams

    Optional min(Comparator comparator)
    Optional max(Comparator comparator) sucht nach dem minimalen/maximalen Element basierend auf dem übergebenen Komparator;

  • findFirst()– holt das erste Element des Streams:

    Stream.of(1, 2, 3, 4, 9).findFirst();
  • allMatch(Predicate predicate)– gibt true zurück , wenn alle Elemente des Streams die Bedingung erfüllen. Wenn ein Element gefunden wird, für das das Ergebnis des Aufrufs der Prädikatfunktion false ist , stoppt der Operator das Scannen der Elemente und gibt false zurück :

    Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
  • anyMatch(Predicate predicate)– gibt true zurück , wenn mindestens ein Element des Streams die Bedingung erfüllt predicate:

    Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
  • noneMatch(Predicate predicate)– gibt true zurück , wenn nach dem Durchlaufen aller Elemente des Streams keines von ihnen die Bedingung erfüllt predicate:

    Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Und zum Schluss möchte ich mir einige Methoden ansehen Collectors:
  • toList()– sammelt Elemente in List:

    List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
  • toSet()– sammelt Elemente in einer Menge:

    Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
  • counting()— Zählt die Anzahl der Elemente:

    Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting());
  • joining()

  • joining(CharSequence delimiter)

  • joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)– Sammelt Elemente in einer Zeile. Zusätzlich können Sie ein Trennzeichen sowie ein Präfix und Suffix für die gesamte Sequenz angeben:

    String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining());
           System.out.println(a); // super
    
           String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-"));
           System.out.println(b); // s-u-p-e-r
    
           String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]"));
           System.out.println(c);  // [ s -> u -> p -> e -> r ]
  • summingInt(ToIntFunction mapper)

  • summingLong(ToLongFunction mapper)

  • summingDouble(ToDoubleFunction mapper)– ein Kollektor, der Objekte in int/long/double umwandelt und die Summe berechnet.

Nützliche Links: PS: Scheuen Sie sich nicht, uns mit Likes zu überhäufen ^ : ^
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION