Die in Java 8 eingeführte Stream-API wird zum Verarbeiten von Sammlungen von Objekten verwendet. Ein Stream ist eine Folge von Objekten, die verschiedene Methoden unterstützt, die per Pipeline verarbeitet werden können, um das gewünschte Ergebnis zu erzielen. Bevor wir fortfahren, lassen Sie uns den Unterschied zwischen Collection und Streams diskutieren, um zu verstehen, warum dieses Konzept eingeführt wurde.

Java-Stream-Tutorial

Notiz: 

  • Wenn wir eine Gruppe von Objekten als eine Einheit darstellen möchten, sollten wir uns für eine Sammlung entscheiden .
  • Aber wenn wir Objekte aus der Sammlung verarbeiten wollen, sollten wir uns für Streams entscheiden.

Wenn wir das Konzept von Streams verwenden wollen, dann ist stream() die zu verwendende Methode. Als Schnittstelle steht Stream zur Verfügung.

Stream s = c.stream();

Im obigen Pre-Tag bezieht sich „c“ auf die Sammlung. In der Sammlung rufen wir also die Methode stream() auf und speichern sie gleichzeitig als Stream-Objekt. Von nun an erhalten wir auf diese Weise das Stream-Objekt.

Hinweis: Streams sind im Dienstprogrammpaket von java mit dem Namen java.util.stream vorhanden

Beginnen wir nun mit den grundlegenden Komponenten von Streams. Sie wie aufgeführt und wie folgt:

  • Folge von Elementen
  • Quelle
  • Aggregierte Operationen
  • Verrohrung
  • Interne Iteration

Funktionen von Java-Stream?

  • Ein Stream ist keine Datenstruktur, sondern nimmt Eingaben von den Collections-, Arrays- oder I/O-Kanälen entgegen.
  • Streams ändern nicht die ursprüngliche Datenstruktur, sie liefern nur das Ergebnis gemäß den Pipeline-Methoden.
  • Jede Zwischenoperation wird träge ausgeführt und gibt als Ergebnis einen Strom zurück, daher können verschiedene Zwischenoperationen in einer Pipeline verarbeitet werden. Terminaloperationen markieren das Ende des Streams und geben das Ergebnis zurück.

Bevor Sie mit dem Konzept fortfahren, betrachten Sie ein Beispiel, in dem wir eine ArrayList von Ganzzahlen haben, und wir nehmen an, dass wir einen Filter anwenden, um nur gerade Zahlen aus dem eingefügten Objekt zu erhalten.

Java-Streams

Wie funktioniert Stream intern?

In Strömen,

  • Um aus den Objekten herauszufiltern, haben wir eine Funktion namens filter()
  • Um eine Bedingung aufzuerlegen, haben wir eine Prädikatslogik, die nichts anderes als eine funktionale Schnittstelle ist. Hier kann die Funktionsschnittstelle durch einen zufälligen Ausdruck ersetzt werden. Daher können wir direkt die Bedingung check-in unserem Prädikat auferlegen.
  • Um Elemente zu sammeln, verwenden wir Collectors.toList() , um alle erforderlichen Elemente zu sammeln.
  • Zuletzt speichern wir diese Elemente in einer Liste und zeigen die Ausgaben auf der Konsole an.

Beispiel 

Java

// Java Program to illustrate FILTER & COLLECT Operations
 
// Importing input output classes
import java.io.*;
 
// Importing utility class for List and ArrayList classes
import java.util.*;
 
// Importing stream classes
import java.util.stream.*;
 
// Main class
public class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating an ArrayList object of integer type
        ArrayList<Integer> al = new ArrayList<Integer>();
 
        // Inserting elements to ArrayLis class object
        // Custom input integer numbers
        al.add(2);
        al.add(6);
        al.add(9);
        al.add(4);
        al.add(20);
 
        // First lets print the collection
        System.out.println("Printing the collection : "
                           + al);
 
        // Printing new line for better output readability
        System.out.println();
 
        // Stream operations
        // 1. Getting thr stream from this collection
        // 2. Filtering out only even elements
        // 3. Collecting the required elements to List
        List<Integer> ls
            = al.stream()
                  .filter(i -> i % 2 == 0)
                  .collect(Collectors.toList());
 
        // Print the collection after stream operation
        // as stored in List object
        System.out.println(
            "Printing the List after stream operation : "
            + ls);
    }
}
Ausgabe

Sammlung drucken: [2, 6, 9, 4, 20]

Drucken der Liste nach dem Stream-Vorgang: [2, 6, 4, 20]

Erläuterung der Ausgabe: In unser Sammlungsobjekt wurden Elemente mit der Operation add() eingegeben. Nach der Verarbeitung des Objekts, in dem sie durch Streams gespeichert wurden, legen wir eine Bedingung im Prädikat von Streams fest, um nur gerade Elemente zu erhalten, wir erhalten Elemente im Objekt gemäß unserer Anforderung. Daher haben uns Streams auf diese Weise bei der Verarbeitung überbearbeiteter Sammlungsobjekte geholfen.

Diverse Kernoperationen über Streams?

Core-Stream-Operationen

Es gibt im Großen und Ganzen 3 Arten von Operationen, die über Streams übertragen werden, nämlich wie folgt, wie aus dem oben gezeigten Bild ersichtlich:

  1. Zwischenoperationen
  2. Terminalbetrieb
  3. Kurzschlussbetrieb

Diskutieren wir hier Zwischenoperationen nur in Strömen bis zu einer gewissen Tiefe anhand eines Beispiels, um andere Operationen mit theoretischen Mitteln zu ergründen. Es gibt also 3 Arten von Zwischenoperationen, die wie folgt sind:

  • Operation 1: filter()-Methode
  • Operation 2: map()-Methode
  • Operation 3: sorted()-Methode

Alle drei werden im Folgenden besprochen, da sie in fast den meisten Szenarien Hand in Hand gehen, und um ein besseres Verständnis zu ermöglichen, indem Sie sie später verwenden, indem Sie sie in unseren sauberen Java-Programmen unten implementieren. Wie wir bereits im obigen Beispiel untersucht haben, können wir versuchen, verarbeitete Objekte zu filtern, als filter()-Operation interpretiert werden, die über Streams ausgeführt wird. Später sammeln wir die Elemente von diesen verarbeiteten gefilterten Elementen von Objekten zurück zur Liste, indem wir Collectors verwenden, für die wir ein bestimmtes Paket namens java.util.stream mit Hilfe der Methode Collectors.toList() importiert haben. Dies wird in Streams als collect()-Operation bezeichnet, daher werden wir auch hier kein Beispiel nehmen, um sie separat zu besprechen. 

Beispiel:

Java

// Java program to illustrate Intermediate Operations
// in Streams
 
// Importing required classes
import java.io.*;
import java.util.*;
import java.util.stream.*;
 
// Main class
class Test {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        // Creating an integer Arraylist to store marks
        ArrayList<Integer> marks = new ArrayList<Integer>();
 
        // These are marks of the students
        // Considering 5 studemnts so input entries
        marks.add(30);
        marks.add(78);
        marks.add(26);
        marks.add(96);
        marks.add(79);
 
        // Printing the marks of the students before grace
        System.out.println(
            "Marks of students before grace : " + marks);
 
        // Now we want to grace marks by 6
        // using the streams to process over processing
        // collection
 
        // Using stream, we map every object and later
        // collect to List
        // and store them
        List<Integer> updatedMarks
            = marks.stream()
                  .map(i -> i + 6)
                  .collect(Collectors.toList());
 
        // Printing the marks of the students after grace
        System.out.println(
            "Marks of students  after grace : "
            + updatedMarks);
    }
}
Ausgabe
Zeichen der Studenten vor der Gnade: [30, 78, 26, 96, 79]
Noten von Studenten nach der Gnadenfrist: [36, 84, 32, 102, 85]

Hinweis: Für jedes Objekt, wenn es dringend ist, einige Operationen auszuführen, sei es quadratisch, doppelt oder irgendetwas anderes als nur, müssen wir die map()-Funktionsoperation verwenden, andernfalls versuchen Sie, die filter()-Funktionsoperation zu verwenden. 

Nun, Geeks, Sie wissen genau, „warum“ Streams eingeführt wurden, aber Sie sollten sich fragen, „wo“ Sie sie verwenden können. Die Antwort ist sehr einfach, da wir sie in unserem täglichen Leben zu oft verwenden. Daher landen die Geeks in einfacheren Worten, wir sagen direkt, wo immer das Konzept der Sammlung anwendbar ist, das Streams-Konzept kann dort angewendet werden. 

Beispiel aus dem wirklichen Leben

Beispiel 1: Im Allgemeinen ist es in der täglichen Welt, wann immer die Daten aus der Datenbank abgerufen werden, wahrscheinlicher, dass wir die Sammlung verwenden, sodass das Streams-Konzept selbst angewendet werden muss, um mit verarbeiteten Daten umzugehen.

Jetzt werden wir Echtzeitbeispiele diskutieren, um Ströme in unserem Leben miteinander in Beziehung zu setzen. Hier werden wir die am weitesten verbreiteten nehmen, nämlich wie folgt:

  1. Streams in einem Lebensmittelgeschäft
  2. Streams im Mobilfunknetz

Beispiel 2: Streams in einem Lebensmittelgeschäft 

Das oben bereitgestellte Bild wurde in Streams implementiert, die wie folgt aussehen: 

List<Integer> transactionsIds = 
    transactions.stream()
                .filter(t -> t.getType() == Transaction.GROCERY)
                .sorted(comparing(Transaction::getValue).reversed())
                .map(Transaction::getId)
                .collect(toList());

Beispiel 3: Streams im Mobilfunknetz 

In ähnlicher Weise können wir uns für ein anderes weit verbreitetes Konzept entscheiden, nämlich den Umgang mit unseren Handynummern. Hier werden wir keine Listings vorschlagen, sondern lediglich demonstrieren, wie das Stream-Konzept in mobilen Netzwerken von verschiedenen Dienstanbietern auf der ganzen Welt verwendet wird.

Die Sammlung kann eine beliebige Anzahl von Objekten enthalten, also sei „mobileNumber“ eine Sammlung und lasse sie verschiedene Handynummern enthalten, sagen wir, sie enthält mehr als 100 Nummern als Objekte. Nehmen wir nun den einzigen Träger namens „Airtel“ an, mit dem wir eine Nachricht senden sollen, wenn es in einem Land zu einer Migration zwischen Staaten kommt. Hier wird also das Streams-Konzept so angewendet, als ob wir beim Umgang mit allen Mobiltelefonnummern nach diesem Anbieter Ausschau halten würden, indem wir die filter()-Methodenoperation von Streams verwenden. Auf diese Weise sind wir in der Lage, die Nachrichten zuzustellen, ohne nach allen Mobiltelefonnummern Ausschau zu halten und dann die Nachricht zuzustellen, was unpraktisch erscheint, da wir jetzt bereits zu spät sind, um sie zuzustellen. Auf diese Weise helfen diese Zwischenoperationen, nämlich filter(), collect(), map(), in der realen Welt aus.

Ich hoffe, Sie, die Benutzer, erkennen inzwischen die Leistungsfähigkeit von Streams in Java, als ob wir die gleiche Aufgabe erledigen müssten, die wir für die Zuordnung zu jedem Objekt benötigen, indem wir die Codelänge erhöhen und die Optimalität unseres Codes verringern. Mit der Verwendung von Streams können wir unabhängig von den im Objekt enthaltenen Elementen in einer einzigen Zeile arbeiten, da wir es beim Konzept der Streams mit dem Objekt selbst zu tun haben.

Hinweis: filter, sorted und map, die zu einer Pipeline verbunden werden können.