Java Lambda -Ausdrücke sind eine neue Funktion, die von Java 8 eingeführt wird. Sie können als Syntaxzucker für die simulierte funktionelle Programmierung sein. Sie ähneln Schließungen in JavaScript, sind aber etwas anders. Der Hauptzweck besteht darin, eine funktionale Syntax bereitzustellen, um unsere Codierung zu vereinfachen.
Lambda Basic Syntax
Die Grundstruktur von Lambda ist (Argumente) -> Körper, und es gibt mehrere Situationen:
Der Körper muss Anweisungen mit {} enthalten, und {} kann weggelassen werden, wenn nur eine Anweisung vorhanden ist.
Gemeinsame Schreibmethoden sind wie folgt:
(a) -> a * a
(int a, int b) -> a + b
(a, b) -> {return a - b;}
() -> System.out.println (Thread.currentThread (). GetId ())
Funktionalinterface
Konzept
Java Lambda -Ausdrücke basieren auf funktionalen Schnittstellen. Was ist eine funktionale Schnittstelle? Einfach ausgedrückt, es handelt sich um eine Schnittstelle mit nur einer Methode (Funktion). Der Zweck dieser Schnittstelle ist für eine einzelne Operation, die einer einzelnen Funktion entspricht. Gemeinsame Schnittstellen wie Runnable und Comparator sind funktionelle Schnittstellen und sind mit @FunctionAnInterface kommentiert.
Geben Sie ein Beispiel an
Es ist leicht zu verstehen, wenn Sie Thread als Beispiel verwenden. Die Runnable -Schnittstelle ist eine Schnittstelle, die bei der Fadenprogrammierung üblicherweise verwendet wird. Dies enthält eine Methode void run (), die die laufende Logik des Threads ist. Laut der vorherigen Syntax verwenden wir normalerweise eine runnable anonyme Klasse, um wie folgt neue Threads zu erstellen:
neuer Thread (new Runnable () {@Override public void run () {System.out.println (Thread.currentThread (). getId ();}}). start ();Wenn Sie zu viel schreiben, ist es nicht langweilig? Die auf Lambda basierenden Schreibregeln werden wie folgt präzise und klar:
neuer Thread (() -> System.out.println (Thread.CurrentThread (). getId ())). start ();
Achten Sie auf die Parameter des Threads. Die anonyme Implementierung von Runnable wird in einem Satz implementiert und als folgende zum besseren Verständnis geschrieben.
Runnable r = () -> system.out.println (Thread.currentThread (). GetId ());
neuer Thread (r) .Start ();
Natürlich besteht Lambdas Zweck nicht nur darin, genau zu schreiben, sondern den Zweck auf höherer Ebene nach dem Verständnis zusammenzufassen.
Schauen wir uns ein weiteres Beispiel eines Komparators an. Nach der traditionellen Schreibmethode wie folgt:
Integer [] a = {1, 8, 3, 9, 2, 0, 5}; arrays.sort (a, neuer Komparator <Integer> () {@Override public int compare (Integer O1, Integer O2) {return o1 - o2;}});Lambda -Ausdrücke werden wie folgt geschrieben:
Integer [] a = {1, 8, 3, 9, 2, 0, 5};
Arrays.sort (a, (O1, O2) -> O1 - O2);
Funktionale Schnittstellen in JDK
Damit die vorhandene Klassenbibliothek Lambda -Ausdrücke direkt verwenden konnte, gab es in Java 8 einige Schnittstellen, die als funktionale Schnittstellen gekennzeichnet waren:
Java 8 wurde ein neues Paket Java.util.Function hinzugefügt, das die häufig verwendete funktionale Schnittstelle bringt:
In addition, more specific functions are added to the processing of basic types, including: BooleanSupplier, DoubleBinaryOperator, DoubleConsumer, DoubleFunction<R>, DoublePredicate, DoubleSupplier, DoubleToIntFunction, DoubleToLongFunction, DoubleToLongFunction, DoubleUnaryOperator, IntBinaryOperator, IntConsumer, IntFunction<R>, IntPredicate, IntSupplier, IntToDoubleFunction, IntToLongFunction, IntUnaryOperator, LongBinaryOperator, LongConsumer,LongFunction<R>, LongPredicate, LongSupplier, LongToDoubleFunction,LongToIntFunction, LongUnaryOperator, ToDoubleBiFunction<T, U>, ToDoubleFunction<T>,ToIntBiFunction<T, U>, Tintfunction <t>, tolongbifunction <t, u>, tolongfunction <t>. In Kombination mit den oben genannten funktionalen Schnittstellen können Sie die Rolle der Grenzfläche auf einen Blick durch den Klassennamen dieser grundlegenden funktionalen Schnittstellen sehen.
Erstellen Sie eine funktionale Schnittstelle
Manchmal müssen wir selbst eine funktionale Schnittstelle implementieren, und die Methode ist sehr einfach. Zuerst müssen Sie sicherstellen, dass diese Schnittstelle nur einen Funktionsvorgang haben kann, und dann @FunctionAlalinterface am Schnittstellentyp kommentieren.
Typ Derivation
Die Typableitung ist die Grundlage für Lambda -Ausdrücke, und der Prozess der Typableitung ist der Kompilierungsprozess von Lambda -Ausdrücken. Der folgende Code ist ein Beispiel:
Funktion <String, Integer> Strtoint = str -> Integer.ParseInt (str);
Während der Zusammenstellung lautet der Prozess der Typableitung, die ich verstehe, wie folgt:
Der Zieltyp ist hier der Schlüssel, und die Methodensignatur wird über den Zieltyp erhalten und dann mit dem Lambda -Ausdruck verglichen.
Methodenreferenz
Die Grundlage der Methodenreferenz (Methodenreferenz) ist auch eine funktionale Schnittstelle, die direkt als funktionale Schnittstelle implementiert werden kann, die gleiche Funktion wie Lambda -Ausdrücke hat und auch von der Typableitung abhängt. Methodenreferenzen können als Vereinfachung von Lambda -Ausdrücken angesehen werden, die nur eine Methode aufrufen.
Die von der Methode verwiesene Syntax lautet: type :: methodName oder instaconName :: methodName, und der dem Konstruktor entsprechende MethodName ist neu.
Zum Beispiel wurden die Beispiele oben verwendet:
Funktion <String, Integer> Strtoint = str -> Integer.ParseInt (str);
Die entsprechende Methodenreferenz ist
Funktion <String, Integer> Strtoint = Integer :: ParseInt;
Gemäß der Art der Methode sind Methodenreferenzen hauptsächlich in die folgenden Typen unterteilt: Konstruktormethodenreferenz, statische Methodenreferenz, Instanzmethodenreferenz zur Instanz, Instanzmethode Referenz auf Typ usw.
Referenz für Konstruktormethoden
Die Syntax ist: Typ :: New. Beispielsweise besteht die folgende Funktion darin, eine Zeichenfolge in ein Array umzuwandeln
Methodenreferenz schreiben
Funktion <String, Integer> Strtoint = Integer :: New;
Lambda schreiben
Funktion <String, Integer> Strtoint = str -> New Integer (str);
Traditionelles Schreiben
Funktion <String, Integer> Strtoint = Neue Funktion <String, Integer> () {@Override public Integer anwenden (String str) {return New Integer (str); }};
Array Constructor Referenz
Die Syntax ist: Typ [] :: New. Beispielsweise besteht die folgende Funktion darin, ein String -Array der angegebenen Länge zu konstruieren
Methodenreferenz schreiben
Funktion <Integer, String []> FixedArray = String [] :: New;
Methodenreferenz schreiben
Funktion <Integer, String []> FixedArray = Länge -> neue String [Länge];
Traditionelles Schreiben
Funktion <Integer, String []> FixedArray = Neue Funktion <Integer, String []> () {@Override public String [] anwenden (Integer Länge) {neuer String zurückgeben [Länge]; }};Statische Methodenreferenz
Die Syntax ist: Typ :: New. Da die folgende Funktion auch verwendet wird, um Strings in Arrays umzuwandeln
Methodenreferenz schreiben
Funktion <String, Integer> Strtoint = Integer :: ParseInt;
Lambda schreiben
Funktion <String, Integer> Strtoint = str -> Integer.ParseInt (str);
Traditionelles Schreiben
Funktion <String, Integer> Strtoint = Neue Funktion <String, Integer> () {@Override public Integer anwenden (String str) {return Integer.ParSint (str); }};Instanzmethode Referenz auf eine Instanz
Die Syntax ist: InstalcaNAME :: methodName. Beispielsweise wird die folgende Beurteilungsfunktion verwendet, um festzustellen, ob der angegebene Name in der Liste vorhanden ist
Liste <String> names = arrays.aslist (neuer String [] {"Zhang san", "li si", "wang wu"});
Prädikat <string> checkNameExists = names :: enthält;
System.out.println (checkNameExists.test ("Zhang san"));
System.out.println (checkNameExists.test ("Zhang si"));
Instanzmethode Referenz zum Typen
Die Syntax ist: Typ :: methodName. Die Laufzeitreferenz bezieht sich auf ein Objekt im Kontext, z. B. die folgende Funktion, um die Länge der Zeichenfolge zurückzugeben
Funktion <String, Integer> CalcStLength = String :: Länge; System.out.println (CalcStLength.Apply ("Zhang SAN"); LIST <string> names = arrays.aslist (new String [] {"Zhangsan", "Lisi", "Wangwu"}).
Beispielsweise hat die folgende Funktion ein Separator angegeben, um die Zeichenfolge in ein Array aufzuteilen
Bifunction <String, String, String []> split = string :: split;
String [] names = split.apply ("Zhangsan, Lisi, Wangwu", ",");
System.out.println (arrays.toString (Namen));
Stream -Objekte
Konzept
Was ist Stream? Der Stream hier unterscheidet sich von InputStream und OutputStream in IO. Der Stream befindet sich im Paket java.util.stream und wird auch neu zu Java 8 hinzugefügt. Stream ist nur eine Reihe von Elementen, die serielle parallele Aggregationsoperationen unterstützen, die als verbesserte Version einer Sammlung oder Iteratorin verstanden werden können. Was ist eine Aggregationsoperation? Um ein einfaches Beispiel zu geben, umfassen gemeinsame, maximale, minimale, summe, sortierende, filtering usw. mittlere, maximale, minimale, summe, sortieren, filtern usw.
Mehrere Merkmale des Streams:
Einzelverarbeitung. Nach Abschluss einer Verarbeitung ist der aktuelle Strom geschlossen.
Unterstützen Sie gemeinsame Möglichkeiten, um Streams in parallelen Operationen zu erhalten
Holen Sie sich aus der Sammlung
Sammlung.Stream ();
Sammlung.Parallelsstream ();
Statische Fabrik
Arrays.Stream (Array)
Stream.of (t…)
Intstream.range ()
Hier geben wir nur eine kurze Einführung in den Stream, und es werden spezifische Anwendungen unten aufgeführt. Wenn Sie über die Beziehung zwischen Stream- und Lambda -Ausdrücken sprechen möchten, gibt es tatsächlich keine besonders enge Beziehung. Es ist nur so, dass Lambda -Ausdrücke die Verwendung von Strom erheblich erleichtern. Ohne Lambda -Ausdrücke werden während der Verwendung von Stream eine große Anzahl anonymer Klassen generiert, was sehr umständlich ist.
Geben Sie ein Beispiel an
Die folgenden Demos hängen vom Mitarbeiterobjekt und dem Listenobjekt ab, das aus dem Mitarbeiterobjekt besteht.
public class Angestellter {privater String -Name; privater String Sex; privates int Alter; öffentlicher Mitarbeiter (String -Name, String Sex, int ARTER) {Super (); this.name = name; this.sex = sex; this.age = Alter; } public String getName () {return name; } public String getSex () {Return Sex; } public int getage () {return ay; } @Override public String toString () {StringBuilder builder = new StringBuilder (); Builder.Append ("Mitarbeiter {name ="). append (name) .Append (", sex ="). append (sex) .Append (", age ="). append (Alter) .Append ("}"); return Builder.toString (); }} List <Speakete> Employees = New ArrayList <> (); Mitarbeiter.Add (neuer Mitarbeiter ("Zhang San", "männlich", 25)); Mitarbeiter.Add (neuer Mitarbeiter ("Li Si", "Female", 24)); Mitarbeiter.Add (neuer Mitarbeiter ("Wang Wu", "Female", 23); Mitarbeiter.Add (neuer Mitarbeiter ("Samstag", "männlich", 22); Mitarbeiter.Add (neuer Mitarbeiter ("Sun Qi", "weiblich", 21);Alle Mitarbeiter drucken
Die Sammlung bietet die Foreach -Methode für uns, einzelne Objekte einzeln zu bedienen.
Mitarbeiter.foreach (e -> system.out.println (e));
oder
Mitarbeiter.Stream (). foreach (e -> system.out.println (e));
Nach Alter sortieren
Collections.sort (Mitarbeiter, (e1, e2) -> e1.getage () - e2.getage ());
Mitarbeiter.foreach (e -> system.out.println (e));
oder
Mitarbeiter.Stream (). sortiert ((e1, e2) -> e1.getage () -e2.getage ()). foreach (e -> system.out.println (e));
Drucken Sie den ältesten weiblichen Angestellten
max/min gibt das größte/min -Element unter bestimmten Sortierbedingungen zurück
Mitarbeiter MaxageFemaleAmeeee = Mitarbeiter.Stream () .Filter (e -> "weiblich" .Equals (e.getSex ()) .max ((e1, e2) -> e1.getage () -e2.getage ()) .get ();
Männliche Mitarbeiter ausdrucken, die älter als 20 Jahre alt sind
filtert Elemente, die den Kriterien entsprechen
Mitarbeiter.Stream ()
.Filter (e -> e.getage ()> 20 && "männlich" .Equals (e.getSex ()))
.foreach (e -> system.out.println (e));
Drucken Sie die beiden ältesten männlichen Mitarbeiter aus
Die Grenzmethode fängt begrenzte Elemente ab
Mitarbeiter.
Drucken Sie die Namen aller männlichen Mitarbeiter aus, verwenden Sie, getrennt
MAP, um einen neuen Stream nach der Ausführung der angegebenen Funktion zu bilden.
String MaleAmpleTeSnames = Mitarbeiter.Stream () .MAP (e -> e.getName ()) .Collect (sammel
Statistische Informationen
IntsummaryStatistics, DoubleSummaryStatistics und LongSummyStatistics enthält die zusammenfassenden Daten im Stream.
IntsummaryStatistics stat = Mitarbeiter.Stream () .Maptoint (Mitarbeiter :: Getage) .SummyStatistics (); System.out.println ("Gesamtzahl der Mitarbeiter:" + stat.getCount ()); System.out.println ("Maximal Age:" + Stat.getMax (); stat.getmin ()); System.out.println ("Durchschnittsalter:" + stat.getAverage ());Zusammenfassen
Lambda -Ausdrücke können in der Tat viel Code reduzieren und die Produktivität verbessern. Natürlich gibt es Nachteile, dh komplexe Ausdrücke schlecht lesbar, oder es kann daran liegen, dass sie nicht sehr daran gewöhnt sind. Wenn Sie sich daran gewöhnen, glaube ich, dass es Ihnen gefallen wird. Alles hat zwei Seiten, es hängt davon ab, wie wir die Vor- und Nachteile ausgleichen, insbesondere in einem Team.
Das obige sind die Informationen, die Java8 Javalambda aussortieren. Wir werden in Zukunft weiterhin relevante Informationen hinzufügen. Vielen Dank für Ihre Unterstützung für diese Website!