Einführung in Lambda-Ausdrücke, den syntaktischen Zucker von Java 8
Empfohlenes kostenloses Lernen: Java-Grundlagen-Tutorial
1. Einführung in Lambda-Ausdrücke
Lambda-Ausdrücke sind eine neue Funktion von Java8 und eine der lohnenswertesten neuen Funktionen in Java8. (Eine weitere neue Funktion ist die Streaming-Programmierung.)
Ein Lambda-Ausdruck ist im Wesentlichen eine
anonyme Methode
. Mit dieser anonymen Methode können Siedie Methoden in der Schnittstelle implementieren
.匿名方法
。可以使用这个匿名方法,实现接口中的方法
。功能:通常使用Lambda表达式,是为了
简化接口实现
的。关于接口实现可以有多种方式实现,例如:①设计接口的实现类、②使用匿名内部类。但是③使用lambda表达式,比这两种方式都简单。要求:lambda表达式,
只能实现函数式接口
:即一个接口中,要求实现类必须实现的抽象方法,有且只有一个。
@FunctionalInterface注解
,用在接口之前,用来判断接口是否是一个函数式接口。如果不是函数式接口会报错。功能类似于@Override。
二、Lambda表达式语法
lambda表达式本质上是一个匿名方法,因此再写lambda表达式时,不需要关心方法名是什么,也不需要关心返回值类型。只需要关心两部分:
参数列表
、方法体
。
- ()参数部分:方法的参数列表,要求和实现的接口中的方法参数部分一致,包括参数的数量和类型。
- {}方法体部分:方法的实现部分,如果接口中定义的方法有返回值,则在实现时,注意返回值的返回。
- -> :分隔参数部分和方法体部分。
Lambda表达式基础语法:(参数) ->{ 方法体}
下面定义6种参数和返回值各不相同的
函数式接口
,分别使用lambda表达式对接口中的方法进行实现:
下面是针对上面6种函数式接口的lambda表达式实现。
/** * @Description: * @author Guoqianliang * @date 19:50 - 2021/2/15 */public class BasicSyntax { public static void main(String[] args) { // 1.实现无参数,无返回值的函数式接口 NoneReturnNoneParameter lambda1 = () -> { System.out.println("这是无参,无返回值的方法"); }; lambda1.test(); // 2.实现一个参数,无返回值的函数式接口 NoneReturnSingleParameter lambda2 = (int a) -> { System.out.println("这是一个参数,无返回值的方法,参数a:" + a); }; lambda2.test(10); // 3.实现多个参数,无返回值的函数式接口 NoneReturnMutipleParameter lambda3 = (int a, int b) -> { System.out.println("这是多个参数,无返回值的方法,参数a=" + a + ",b=" + b); }; lambda3.test(10, 20); // 4.实现无参数,有返回值有返回值的函数式接口 SingleReturnNoneParameter lambda4 = () -> { System.out.println("这是无参数,有返回值的方法,返回值是:"); return 10; }; System.out.println(lambda4.test()); // 5.实现一个参数,有返回值的函数式接口 SingleReturnSingleParameter lambda5 = (int a) -> { System.out.println("这是一个参数,有返回值的方法,返回值是:"); return a; }; System.out.println(lambda5.test(10)); // 6.实现多个参数,有返回值的函数式接口 SingleReturnMutipleParameter lambda6 = (int a, int b) -> { System.out.println("这是多个参数,有返回值的方法,返回值是:"); return a + b; }; System.out.println(lambda6.test(1, 2)); }}
语法精简进阶:
- 参数列表的参数类型可以省略。
- 如果参数列表中的参数有且只有一个,可以省略小括号。
- 如果方法体中只有一条语句,可以省略大括号。(注:如果这条语句是返回语句,省略了大括号后也要把return关键字省略)
三、函数引用
lambda表达式是为了简化接口。在lambda表达式中,不应该出现比较复杂的逻辑。如果需要处理的逻辑比较复杂,一般情况会单独写一个方法。在lambda表达式中直接引用这个方法即可。即
引用一个已经存在的方法,使其代替lambda表达式完成接口的实现。
1.静态方法引用
语法:
类::静态方法
- 在引用的方法后面,不要添加小括号。
- 引用的这个方法,参数(数量、类型)和返回值,必须要跟接口中定义的一致。
/** * @Description: 方法引用 * @author Guoqianliang * @date 0:26 - 2021/2/16 */public class Lambda1 { private static interface Calculate { int calculate(int a, int b); } private static int calculate(int x, int y) { if (x > y) { return x - y; } else if (x <p><strong>2.非静态方法引用</strong></p><blockquote> <p>语法:<code>对象::非静态方法</code></p> <ul> <li>在引用的方法后面,不要添加小括号。</li> <li>引用的这个方法,参数(数量、类型)和返回值,必须要跟接口中定义的一致。</li> </ul> </blockquote><pre class="brush:php;toolbar:false">/** * @Description: 方法引用 * @author Guoqianliang * @date 0:26 - 2021/2/16 */public class Lambda1 { private static interface Calculate { int calculate(int a, int b); } // 非静态方法 private int calculate2(int a, int b) { if (a != b) { return a - b; } return a + b; } public static void main(String[] args) { // 非静态方法引用 Calculate calculate2 = new Lambda1()::calculate2; System.out.println(calculate.calculate(10, 20)); }}
3.构造方法引用
语法:
类名::new
- 可以通过接口中的方法的参数,区分引用不同的构造方法。
- 如果某一个函数式接口中定义的方法,仅仅是为了得到一个类的对象。此时就可以使用构造方法的引用,简化这个方法的实现。
/** * @Description: 构造方法引用 * @author Guoqianliang * @date 11:20 - 2021/2/16 */public class Lambda2 { @FunctionalInterface private interface GetPersonWithNoneParameter { Person get(); } @FunctionalInterface private interface GetPersonWithSingleParameter { Person get(String name); } @FunctionalInterface private interface GetPersonWithMutipleParameter { Person get(String name, int age); } private static class Person { String name; int age; public Person() { System.out.println("Person类的无参构造方法执行了"); } public Person(String name) { this.name = name; System.out.println("Person类的有参构造方法执行了"); } public Person(String name, int age) { this.name = name; this.age = age; System.out.println("Person类的两个参数的构造方法执行了"); } } public static void main(String[] args) { // 1.使用lambda表达式,实现GetPersonWithNoneParameter接口 GetPersonWithNoneParameter getPerson = Person::new; // 2.使用lambda表达式,实现GetPersonWithSingleParameter接口 GetPersonWithSingleParameter getPerson2 = Person::new; // 3.使用lambda表达式,实现GetPersonWithMutipleParameter接口 GetPersonWithMutipleParameter getPerson3 = Person::new; System.out.println(getPerson.get()); System.out.println(getPerson2.get("树先生")); System.out.println(getPerson3.get("你好", 23)); }}
4.对象方法的特殊引用
使用lambda表达式实现某些接口时,如果lambda表达式中包含了某一个对象,此时方法体中,直接使用这个对象调用它的某一个方法就可以完成整体的逻辑。
/** * @Description: 对象方法的特殊应用 * @author Guoqianliang * @date 11:54 - 2021/2/16 */public class Lambda3 { @FunctionalInterface private interface MyInterface { // String get(Person person); void set(Person person, String name); } private static class Person { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } } public static void main(String[] args) { Person p1 = new Person(); p1.setName("小明");// 逻辑实现只是为了获取到对象的名字// MyInterface lambda2 = Person::getName;// System.out.println(lambda2.get(p1)); // 逻辑实现只是为了给对象的某些属性进行赋值 MyInterface lambda1 = (x, n) -> x.setName(n); MyInterface lambda2 = Person::setName; lambda2.set(p1, "李华"); System.out.println(p1.getName()); }}
四、Lambda表达式需要注意的问题
Funktion: Lambda-Ausdrücke werden normalerweise verwendet, um如果用到
局部变量
die Schnittstellenimplementierung zu vereinfachen
. Es gibt viele Möglichkeiten, Schnittstellen zu implementieren, z. B.: ① Entwerfen Sie die Implementierungsklasse der Schnittstelle, ② Verwenden Sie anonyme innere Klassen. Aber ③ Die Verwendung des Lambda-Ausdrucks ist einfacher als diese beiden Methoden. 2. Lambda-Ausdruckssyntax 🎜🎜🎜🎜Der Lambda-Ausdruck ist im Wesentlichen eine anonyme Methode. Wenn Sie also einen Lambda-Ausdruck schreiben, müssen Sie sich nicht um den Methodennamen oder den Rückgabewerttyp kümmern. Sie müssen sich nur um zwei Teile kümmern:Anforderungen: Lambda-Ausdrücke,
kann nur funktionale Schnittstellen implementieren
: Das heißt, in einer Schnittstelle gibt es nur eine abstrakte Methode, die die Implementierungsklasse implementieren muss.@FunctionalInterface-Annotation
wird vor der Schnittstelle verwendet, um zu bestimmen, ob die Schnittstelle eine funktionale Schnittstelle ist. Handelt es sich nicht um eine funktionsfähige Schnittstelle, wird ein Fehler gemeldet. Die Funktionalität ähnelt @Override.
Parameterliste
und Methodenkörper
. 🎜🎜🎜🎜() Parameterteil: Die Parameterliste der Methode muss mit dem Methodenparameterteil in der implementierten Schnittstelle übereinstimmen, einschließlich der Anzahl und Art der Parameter. 🎜{}Methodenkörperteil: Der Implementierungsteil der Methode. Wenn die in der Schnittstelle definierte Methode einen Rückgabewert hat, achten Sie bei der Implementierung auf den Rückgabewert. 🎜->: Trennt den Parameterteil und den Methodenkörperteil. /** * @Description: * @author Guoqianliang * @date 13:05 - 2021/2/16 */public class Lambda4 { public static void main(String[] args) { // 1.定义一个局部变量 int x = 10; // 2.使用lambda表达式实现接口 LambdaTest lambda = () -> { System.out.println("x=" + x); }; // 3. 无法修改常量x // x=20; }}@FunctionalInterfaceinterface LambdaTest { void test();}
funktionalen Schnittstellen
mit unterschiedlichen Parametern und Rückgabewerten definiert und Lambda-Ausdrücke verwendet, um die Methoden in der Schnittstelle zu implementieren: 🎜🎜🎜 
verweist auf eine vorhandene Methode, sodass sie den Lambda-Ausdruck ersetzen kann, um die Implementierung der Schnittstelle abzuschließen.
🎜🎜🎜🎜1. Statische Methodenreferenz🎜🎜🎜🎜 Syntax: Klasse::statische Methode
🎜🎜🎜Fügen Sie nach der referenzierten Methode keine Klammern hinzu. 🎜Die Parameter (Anzahl, Typ) und der Rückgabewert der referenzierten Methode müssen mit den in der Schnittstelle definierten übereinstimmen. 🎜rrreee🎜🎜2. Nicht-statische Methodenreferenz🎜🎜🎜🎜 Syntax: Object::non-static method
🎜🎜🎜Nach der referenzierten Methode nicht hinzufügen Klammern. 🎜Die Parameter (Anzahl, Typ) und der Rückgabewert der referenzierten Methode müssen mit den in der Schnittstelle definierten übereinstimmen. 🎜rrreee🎜🎜3. Konstruktor-Methodenreferenz🎜🎜🎜🎜 Syntax: Klassenname::new
🎜🎜🎜Sie können verschiedene Referenzen durch die Parameter der Methode in unterscheiden die Schnittstellenkonstruktionsmethode. 🎜Wenn eine in einer funktionalen Schnittstelle definierte Methode nur dazu dient, ein Objekt einer Klasse abzurufen. An dieser Stelle können Sie den Verweis auf die Konstruktormethode verwenden, um die Implementierung dieser Methode zu vereinfachen. 🎜rrreee🎜🎜4. Spezielle Verweise auf Objektmethoden🎜🎜🎜🎜Wenn der Lambda-Ausdruck zur Implementierung bestimmter Schnittstellen ein Objekt enthält, verwenden Sie einfach dieses Objekt im Methodenkörper um eine seiner Methoden aufzurufen, um die Gesamtlogik zu vervollständigen. 🎜🎜rrreee🎜🎜4. Probleme, die bei Lambda-Ausdrücken beachtet werden müssen🎜🎜🎜🎜Wenn lokale Variablen
verwendet werden, werden sie standardmäßig als Konstanten deklariert und der Wert kann nicht geändert werden. 🎜🎜rrreee🎜🎜🎜Verwandte Lernempfehlungen: 🎜🎜🎜Java-Grundlagen🎜🎜🎜🎜Das obige ist der detaillierte Inhalt vonEinführung in Lambda-Ausdrücke, den syntaktischen Zucker von Java 8. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

In C++ gibt es zwei Möglichkeiten, Ausnahmen mit Lambda-Ausdrücken zu behandeln: Die Ausnahme mit einem Try-Catch-Block abfangen und die Ausnahme im Catch-Block behandeln oder erneut auslösen. Mithilfe einer Wrapper-Funktion vom Typ std::function kann die Methode try_emplace Ausnahmen in Lambda-Ausdrücken abfangen.

Java8 berechnet das Datum vor einem Jahr oder ein Jahr später mithilfe der minus()-Methode, um das Datum vor einem Jahr zu berechnen packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[ ]args ){LocalDatetoday=LocalDate.now();LocalDate previousYear=today.minus(1,ChronoUni

In C++ ist ein Abschluss ein Lambda-Ausdruck, der auf externe Variablen zugreifen kann. Um einen Abschluss zu erstellen, erfassen Sie die äußere Variable im Lambda-Ausdruck. Abschlüsse bieten Vorteile wie Wiederverwendbarkeit, Ausblenden von Informationen und verzögerte Auswertung. Sie sind in realen Situationen nützlich, beispielsweise bei Ereignishandlern, bei denen der Abschluss auch dann noch auf die äußeren Variablen zugreifen kann, wenn diese zerstört werden.

Zu den Vorteilen von Lambda-Ausdrücken in der C++-Multithread-Programmierung gehören Einfachheit, Flexibilität, einfache Parameterübergabe und Parallelität. Praktischer Fall: Verwenden Sie Lambda-Ausdrücke, um Multithreads zu erstellen und Thread-IDs in verschiedenen Threads zu drucken, was die Einfachheit und Benutzerfreundlichkeit dieser Methode demonstriert.

C++-Lambda-Ausdrücke unterstützen Abschlüsse, die Funktionsbereichsvariablen speichern und sie für Funktionen zugänglich machen. Die Syntax lautet [capture-list](parameters)->return-type{function-body}. Capture-Liste definiert die zu erfassenden Variablen. Sie können [=] verwenden, um alle lokalen Variablen nach Wert zu erfassen, [&], um alle lokalen Variablen nach Referenz zu erfassen, oder [Variable1, Variable2,...], um bestimmte Variablen zu erfassen. Lambda-Ausdrücke können nur auf erfasste Variablen zugreifen, den ursprünglichen Wert jedoch nicht ändern.

Es gibt drei Möglichkeiten, Lambda-Ausdrücke externer Variablen in C++ zu erfassen: Erfassung nach Wert: Erstellen Sie eine Kopie der Variablen. Erfassen nach Referenz: Rufen Sie eine Variablenreferenz ab. Gleichzeitige Erfassung nach Wert und Referenz: Ermöglicht die Erfassung mehrerer Variablen, entweder nach Wert oder nach Referenz.

In C++ können Sie Lambda-Ausdrücke als Funktionsparameter verwenden, um die Flexibilität von Rückruffunktionen zu erreichen. Konkret: Parameterübergabe: Wickeln Sie den Lambda-Ausdruck durch std::function und übergeben Sie ihn in Form eines Funktionszeigers an die Funktion. Rückgabewertverarbeitung: Geben Sie den Rückgabewerttyp an, wenn Sie den Rückruffunktionszeiger mit std::function deklarieren. Praktischer Fall: Optimieren Sie Rückrufe bei der GUI-Ereignisverarbeitung, vermeiden Sie die Erstellung unnötiger Objekte oder Funktionszeiger und verbessern Sie die Einfachheit und Wartbarkeit des Codes.

So berechnen Sie das Datum eine Woche später in Java8. In diesem Beispiel wird das Datum eine Woche später berechnet. Das LocalDate-Datum enthält keine Zeitinformationen. Seine plus()-Methode wird zum Hinzufügen von Tagen, Wochen und Monaten verwendet. Die ChronoUnit-Klasse deklariert diese Zeiteinheiten. Da LocalDate ebenfalls ein unveränderlicher Typ ist, müssen Sie Variablen verwenden, um nach der Rückgabe Werte zuzuweisen. packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[
