[Java] Einführung in den Lambda-Ausdruck

Einführung

Verwenden Sie zum Ausführen eines Threads in Java eine Unterklasse, die die Thread-Klasse erbt, und Es gibt eine Methode, die eine Unterklasse verwendet, die die Runnable-Schnittstelle implementiert. Diesmal wird letzteres als Beispiel für eine kurze Erklärung des Lambda-Ausdrucks genommen.

Function.java


public class Function implements Runnable{
	@Override
	public void run() {
		//Was im Thread zu verarbeiten ist
		System.out.println("hello!");
	}
}

Main.java


public class Main {
	public static void main(String[] args) {
		Thread thread = new Thread(new Function());
		thread.start();
		System.out.println("finish!");
	}
}

Ich denke, die Ausgabe wird so aussehen.

finish!
hello!

Welche Beziehung besteht zwischen der Thread-Klasse und der Runnable-Schnittstelle? Das Strategiemusterdesign des GoF-Designmusters wird verwendet. Grob gesagt soll das Strategiemuster "einen austauschbaren Algorithmus realisieren". Die Klasse, die ursprünglich eine war, ist für den gesamten Verarbeitungsfluss verantwortlich. Teilen wir es in Klassen ein, die für bestimmte Algorithmen zuständig sind. Durch Verwendung des Strategiemusters mit dem Benutzer (Thread-Klasse) Die zu verwendende Seite (die Klasse, die die Runnable-Schnittstelle realisiert) Da es nicht direkt zusammenhängen muss, ist es möglich, einen Algorithmus zu realisieren, der später ersetzt werden kann. (Für diejenigen, die mehr über Strategiemuster erfahren möchten, siehe hier) UML2.png Die Klasse, die die Schnittstelle realisiert hat, ist jedoch kompliziert (FunctionHard-Klasse im UML-Diagramm). Es gibt so etwas wie eine Klasse, die einfachen Code erfordert (FunctionEasy-Klasse im UML-Diagramm).

Neue Klassen nacheinander, auch mit einfachem Code Ist es nicht ärgerlich definieren zu müssen? darüber.

Lambda-Style-Effekt

Um das in der Einführung vorgestellte Problem zu lösen, verwenden wir den aus Java SE 8 eingeführten Lambda-Ausdruck. Der folgende Code wird durch einen Lambda-Ausdruck ersetzt, anstatt eine FunctionEasy-Klasse zu erstellen.

Lambda.java


public class Lambda {
	public static void main(String[] args) {
		Runnable r = () -> System.out.println("hello!");
		Thread thread = new Thread(r);
		thread.start();
		System.out.println("finish!");
	}
}

Sie brauchen nur eine Zeile wie diese. Erfrischend! Lambda-Ausdrücke sind "beim Instanziieren einer funktionalen Schnittstelle Sie können sich das als "eine Notation vorstellen, die kein kompliziertes Schreiben erfordert".

Eine Schnittstelle, die nur eine Methode hat, die implementiert werden muss, wird als "funktionale Schnittstelle" bezeichnet. Es wird auch als "SAM-Schnittstelle (Single Abstarct Method)" bezeichnet.

Wie Sie aus SAM sehen können, gibt es also nur eine abstrakte Methode Welche Methode implementiert der Lambda-Ausdruck? Was ist mit Argumenten und Rückgabewerten? Inferenz ist möglich. Es ist nicht erforderlich, den Methodennamen einzeln zu bestimmen. Polymorphismus kann realisiert werden, ohne eine Klasse vorzubereiten, die die Schnittstelle realisiert.

Anonymer Klassen- und Lambda-Ausdruck

Vor Java8 wurde es von einer anonymen Klasse realisiert. Anonyme Klassen werden manchmal als anonyme Klassen bezeichnet.


		Runnable r = new Runnable() {
			@Override
			public void run() {
				System.out.println("hello!");
			}
		}

Es ist lang und unlesbar.

Lambda-Ausdrücke sind in Java 8 erschienen und es ist einfacher geworden, sie zu schreiben.

		Runnable r = () -> {
			System.out.println("hello!");
		}

Die Lambda-Ausdrucksdeklaration besteht aus der Argumentvariablendeklaration und dem Verarbeitungsblock, wie unten gezeigt.

     (Streit) -> {wird bearbeitet; };

"->" Wird als Pfeiloperator bezeichnet.

Lambda-Abkürzung

Einige Lambda-Ausdrücke können weggelassen werden. Folgen wir als Beispiel dem folgenden Prototyp.

Prototyp



		Sample sample = (String a) -> { System.out.println(a);};

Abkürzungsnotation 1

Wenn das Argument nur ** ist, wenn es eines gibt **, können die Klammern "()" weggelassen werden. Außerdem kann auf den Typ des Arguments geschlossen werden, sodass es weggelassen werden kann.

Abkürzungsnotation 1


		Sample sample = a -> { System.out.println(a);};

Abkürzungsnotation 2

Wenn der Methodenkörper aus einer Zeile besteht, können auch die mittlere Klammer "{}" und das Semikolon ";" am Ende des Satzes weggelassen werden. Im Fall einer return-Anweisung kann die Rückgabe ebenfalls weggelassen werden.

Abkürzungsnotation 2


		Sample sample = a -> System.out.println(a);

Abkürzungsnotation 3

Wenn das Argument abgeleitet werden kann, wird außerdem die Methode aufgerufen Klassenname :: Methodenname Objektname :: Methodenname Es kann so weggelassen werden.

Abkürzungsnotation 3


		Sample sample = System.out::println;

Gültigkeitsbereich der Lambda-Ausdrucksvariablen

Anmerkung 1

** Eine Variable mit demselben Namen wie die in der Methode deklarierte lokale Variable kann nicht als Argumentname des Lambda-Ausdrucks verwendet werden. ** ** ** Das Folgende führt zu einem Kompilierungsfehler.

public class Sample {
	public static void main(String[] args) {
		String a = "sample";
		Function f = a -> System.out.println(a); //Error
		//Abkürzung
	}
}

Da der Variablenname a bereits als lokale Variable deklariert wurde, kann er nicht als Argumentname für einen Lambda-Ausdruck verwendet werden.

Anmerkung 2

** Um von innerhalb des Lambda-Ausdrucks auf eine außerhalb des Lambda-Ausdrucks deklarierte lokale Variable zugreifen zu können, muss die lokale Variable endgültig sein. Wenn der endgültige Modifikator nicht angehängt ist, muss er praktisch endgültig sein. ** ** **

Sie können über den Lambda-Ausdruck auf die lokalen Variablen der Methode zugreifen, die den Ausdruck umgibt. (Wenn Sie vor der Konvertierung in einen Lambda-Ausdruck darüber nachdenken, ist das so.) Sie können wie folgt auf die lokalen Variablen der Methode zugreifen, die den Ausdruck innerhalb des Lambda-Ausdrucks deklariert:

"Im Wesentlichen endgültig" bedeutet eine Variable, die sich nicht ändert, auch wenn sie nicht endgültig qualifiziert ist. Wenn Sie den Wert einer lokalen Variablen in einem Lambda-Ausdruck wie unten gezeigt ändern, tritt ein Kompilierungsfehler auf.

public class Sample {
	public static void main(String[] args) {
		String a = "sample";
		Function f = () -> {
			a = "change"; //Error
			System.out.println(a);
		};
		//Abkürzung
	}
}

java.util.function-Paket und Collection-API

Häufig verwendete Funktionsschnittstellen befinden sich im Paket java.util.function. Insbesondere sind die folgenden fünf Funktionsschnittstellen bekannt.

Funktionsschnittstelle Methode Streit Rückgabewert Erläuterung
Consumer<T> void accept(T) Ja Keiner "Verbraucher", der keinen Wert zurückgibt
Supplier<T> T get() Keiner Ja "Lieferant" gibt einen Wert zurück
Predicate<T> boolean test(T) Ja Ja "Bestätigung", die einen booleschen Wert zurückgibt
Function<T, R> R apply(T) Ja Ja "Verarbeitung", die ein Argument empfängt und das Ergebnis des angegebenen Typs zurückgibt
UnaryOperator<T> T apply(T t) Es gibt zwei Ja "Operation", die das Berechnungsergebnis zurückgibt

Die Sammlungs-API verfügt über viele Standardmethoden zum Bearbeiten von Liste und Zuordnung.

Beispielsweise verfügt java.util.List über eine Methode namens * removeIf (Prädikatfilter) *, mit der Elemente entfernt werden, die dem Filter entsprechen. Wenn Sie den Lambda-Ausdruck verwenden, benötigen Sie nur eine Zeile.

RemoveIf.java


import java.util.ArrayList;
import java.util.Arrays;

public class RemoveIf {
	public static void main(String[] args) {

		ArrayList<String> list = new ArrayList<String>(Arrays.asList("aaaa", "bbb", "cc"));

		list.removeIf(v -> v.length() > 3);

		System.out.println(list); //Ergebnis: [bbb, cc]
	}
}

Es gibt viele andere Methoden, mit denen Sie einen Lambda-Ausdruck angeben können. Lassen Sie uns selbst untersuchen und es mit einem Lambda-Ausdruck implementieren, um sich daran zu gewöhnen.

Fazit

Es gibt viele WEB-Anwendungen, deren Serverseite unter Java 8 ausgeführt wird. Daher denke ich, dass die Lambda-Ausdrucks- und Stream-API unvermeidliches Wissen ist, wenn Sie jetzt Java ausführen. Dennoch scheint es einige Dinge zu geben, die im Java-Newcomer-Training nicht gelehrt werden. Ich habe versucht, es für Neulinge so einfach wie möglich zusammenzufassen. Es tut mir leid, wenn es einen Teil gibt, der schwer zu verstehen ist.

Nächstes Mal werde ich die Einführung in die Stream-API in der nächsten Woche zusammenfassen.

(Aktualisiert am 22. Dezember 2019) Fortsetzung etwas → [Java] Einführung in die Stream-API

Recommended Posts

[Java] Einführung in den Lambda-Ausdruck
[Einführung in Java] Über Lambda-Ausdrücke
[Java] Einführung in Java
Einführung in Java
Verwendung von Java-Lambda-Ausdrücken
Ich habe versucht, Java-Lambda-Ausdrücke zusammenzufassen
Verstehen Sie Java 8 Lambda-Ausdrücke
Über Java-Lambda-Ausdrücke
Einführung in den Lambda-Stil
Erläutern Sie Java 8-Lambda-Ausdrücke
Einführung in den Java-Befehl
[Java] Zusammenfassung, wie Lambda-Ausdrücke weggelassen werden
[Java] Einführung in die Stream-API
[Einführung in Janken (ähnliche) Spiele] Java
[Java Silver] Zusammenfassung der Punkte im Zusammenhang mit Lambda-Ausdrücken
[Java] Einführung
Java-Lambda-Ausdruck, der mit Comparator gelernt wurde
[Einführung in Java] Informationen zur Stream-API
Einführung in die funktionale Programmierung (Java, Javascript)
Erste Einführung in Mac (Java-Ingenieur)
Der Ursprung von Java-Lambda-Ausdrücken
Heutzutage Java Lambda Expressions und Stream API
Einführung in Algorithmen mit Java-Suche (Tiefenprioritätssuche)
[Einführung in Java] So schreiben Sie ein Java-Programm
Einführung in web3j
Einführung in Micronaut 1 ~ Einführung ~
Einführung in die Migration
Hallo Java Lambda
[Java] Lambda-Ausdruck
Ausgabe des Buches "Einführung in Java"
Einführung in die Überwachung von Java Touching Prometheus
[Einführung in Java] Informationen zu Variablendeklarationen und -typen
Einfach mit regulären Java-Ausdrücken zu stolpern
Einführung in Doma
Java Lambda Ausdruck
Einführung in Algorithmen mit Java --Search (Breitenprioritätssuche)
[Einführung in Java] Informationen zur Typkonvertierung (Besetzung, Promotion)
Einführung in Algorithmen mit Java --Search (Bit Full Search)
Road to Java Engineer Teil 1 Einführung & Umgebungskonstruktion
Verwendung des Java-Frameworks mit AWS Lambda! ??
[Monatlich 2017/04] Einführung in groovy !! ~ Java Grammatik / Spezifikationsvergleich ~
Verwendung der Java-API mit Lambda-Ausdrücken
Java 8 startet jetzt ~ für jeden und Lambda-Ausdruck ~
Erste Schritte mit Groovy für problematische Java-Ingenieure
[Einführung in Java] Grundlagen der Java-Arithmetik (für Anfänger)
Java-Leistung Kapitel 1 Einführung
Einführung in JAR-Dateien
Änderungen von Java 8 zu Java 11
Summe von Java_1 bis 100
Einführung in Ratpack (8) -Session
Java Neutral Lambda Tabellenausdruck 1
Einführung in Ratpack (6) --Promise
Quarkus rettet Java Lambda! ??
Einführung in Ratpack (9) - Thymeleaf
[Java] Stellen Sie eine Verbindung zu MySQL her
Variationen von Java-Lambda-Ausdrücken
Einführung in PlayFramework 2.7 ① Übersicht