Einführung in Lambda-Ausdrücke, den syntaktischen Zucker von Java 8
Feb 18, 2021 pm 06:09 PMEmpfohlenes 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
.匿名方法
??梢允褂眠@個(gè)匿名方法,實(shí)現(xiàn)接口中的方法
。功能:通常使用Lambda表達(dá)式,是為了
簡化接口實(shí)現(xiàn)
的。關(guān)于接口實(shí)現(xiàn)可以有多種方式實(shí)現(xiàn),例如:①設(shè)計(jì)接口的實(shí)現(xiàn)類、②使用匿名內(nèi)部類。但是③使用lambda表達(dá)式,比這兩種方式都簡單。要求:lambda表達(dá)式,
只能實(shí)現(xiàn)函數(shù)式接口
:即一個(gè)接口中,要求實(shí)現(xiàn)類必須實(shí)現(xiàn)的抽象方法,有且只有一個(gè)。
@FunctionalInterface注解
,用在接口之前,用來判斷接口是否是一個(gè)函數(shù)式接口。如果不是函數(shù)式接口會報(bào)錯(cuò)。功能類似于@Override。
二、Lambda表達(dá)式語法
lambda表達(dá)式本質(zhì)上是一個(gè)匿名方法,因此再寫lambda表達(dá)式時(shí),不需要關(guān)心方法名是什么,也不需要關(guān)心返回值類型。只需要關(guān)心兩部分:
參數(shù)列表
、方法體
。
- ()參數(shù)部分:方法的參數(shù)列表,要求和實(shí)現(xiàn)的接口中的方法參數(shù)部分一致,包括參數(shù)的數(shù)量和類型。
- {}方法體部分:方法的實(shí)現(xiàn)部分,如果接口中定義的方法有返回值,則在實(shí)現(xiàn)時(shí),注意返回值的返回。
- -> :分隔參數(shù)部分和方法體部分。
Lambda表達(dá)式基礎(chǔ)語法:(參數(shù))?->{ 方法體}
下面定義6種參數(shù)和返回值各不相同的
函數(shù)式接口
,分別使用lambda表達(dá)式對接口中的方法進(jìn)行實(shí)現(xiàn):
下面是針對上面6種函數(shù)式接口的lambda表達(dá)式實(shí)現(xiàn)。
/** ?*?@Description: ?*?@author?Guoqianliang ?*?@date?19:50?-?2021/2/15 ?*/public?class?BasicSyntax?{ ????public?static?void?main(String[]?args)?{ ????????//?1.實(shí)現(xiàn)無參數(shù),無返回值的函數(shù)式接口 ????????NoneReturnNoneParameter?lambda1?=?()?->?{ ????????????System.out.println("這是無參,無返回值的方法"); ????????}; ????????lambda1.test(); ????????//?2.實(shí)現(xiàn)一個(gè)參數(shù),無返回值的函數(shù)式接口 ????????NoneReturnSingleParameter?lambda2?=?(int?a)?->?{ ????????????System.out.println("這是一個(gè)參數(shù),無返回值的方法,參數(shù)a:"?+?a); ????????}; ????????lambda2.test(10); ????????//?3.實(shí)現(xiàn)多個(gè)參數(shù),無返回值的函數(shù)式接口 ????????NoneReturnMutipleParameter?lambda3?=?(int?a,?int?b)?->?{ ????????????System.out.println("這是多個(gè)參數(shù),無返回值的方法,參數(shù)a="?+?a?+?",b="?+?b); ????????}; ????????lambda3.test(10,?20); ????????//?4.實(shí)現(xiàn)無參數(shù),有返回值有返回值的函數(shù)式接口 ????????SingleReturnNoneParameter?lambda4?=?()?->?{ ????????????System.out.println("這是無參數(shù),有返回值的方法,返回值是:"); ????????????return?10; ????????}; ????????System.out.println(lambda4.test()); ????????//?5.實(shí)現(xiàn)一個(gè)參數(shù),有返回值的函數(shù)式接口 ????????SingleReturnSingleParameter?lambda5?=?(int?a)?->?{ ????????????System.out.println("這是一個(gè)參數(shù),有返回值的方法,返回值是:"); ????????????return?a; ????????}; ????????System.out.println(lambda5.test(10)); ????????//?6.實(shí)現(xiàn)多個(gè)參數(shù),有返回值的函數(shù)式接口 ????????SingleReturnMutipleParameter?lambda6?=?(int?a,?int?b)?->?{ ????????????System.out.println("這是多個(gè)參數(shù),有返回值的方法,返回值是:"); ????????????return?a?+?b; ????????}; ????????System.out.println(lambda6.test(1,?2)); ????}}
語法精簡進(jìn)階:
- 參數(shù)列表的參數(shù)類型可以省略。
- 如果參數(shù)列表中的參數(shù)有且只有一個(gè),可以省略小括號。
- 如果方法體中只有一條語句,可以省略大括號。(注:如果這條語句是返回語句,省略了大括號后也要把return關(guān)鍵字省略)
三、函數(shù)引用
lambda表達(dá)式是為了簡化接口。在lambda表達(dá)式中,不應(yīng)該出現(xiàn)比較復(fù)雜的邏輯。如果需要處理的邏輯比較復(fù)雜,一般情況會單獨(dú)寫一個(gè)方法。在lambda表達(dá)式中直接引用這個(gè)方法即可。即
引用一個(gè)已經(jīng)存在的方法,使其代替lambda表達(dá)式完成接口的實(shí)現(xiàn)。
1.靜態(tài)方法引用
語法:
類::靜態(tài)方法
- 在引用的方法后面,不要添加小括號。
- 引用的這個(gè)方法,參數(shù)(數(shù)量、類型)和返回值,必須要跟接口中定義的一致。
/** ?*?@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.非靜態(tài)方法引用</strong></p><blockquote> <p>語法:<code>對象::非靜態(tài)方法</code></p> <ul> <li>在引用的方法后面,不要添加小括號。</li> <li>引用的這個(gè)方法,參數(shù)(數(shù)量、類型)和返回值,必須要跟接口中定義的一致。</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); ????} ????//?非靜態(tài)方法 ????private?int?calculate2(int?a,?int?b)?{ ????????if?(a?!=?b)?{ ????????????return?a?-?b; ????????} ????????return?a?+?b; ????} ????public?static?void?main(String[]?args)?{ ????????//?非靜態(tài)方法引用 ????????Calculate?calculate2?=?new?Lambda1()::calculate2; ????????System.out.println(calculate.calculate(10,?20)); ????}}
3.構(gòu)造方法引用
語法:
類名::new
- 可以通過接口中的方法的參數(shù),區(qū)分引用不同的構(gòu)造方法。
- 如果某一個(gè)函數(shù)式接口中定義的方法,僅僅是為了得到一個(gè)類的對象。此時(shí)就可以使用構(gòu)造方法的引用,簡化這個(gè)方法的實(shí)現(xiàn)。
/** ?*?@Description:?構(gòu)造方法引用 ?*?@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類的無參構(gòu)造方法執(zhí)行了"); ????????} ????????public?Person(String?name)?{ ????????????this.name?=?name; ????????????System.out.println("Person類的有參構(gòu)造方法執(zhí)行了"); ????????} ????????public?Person(String?name,?int?age)?{ ????????????this.name?=?name; ????????????this.age?=?age; ????????????System.out.println("Person類的兩個(gè)參數(shù)的構(gòu)造方法執(zhí)行了"); ????????} ????} ????public?static?void?main(String[]?args)?{ ????????//?1.使用lambda表達(dá)式,實(shí)現(xiàn)GetPersonWithNoneParameter接口 ????????GetPersonWithNoneParameter?getPerson?=?Person::new; ????????//?2.使用lambda表達(dá)式,實(shí)現(xiàn)GetPersonWithSingleParameter接口 ????????GetPersonWithSingleParameter?getPerson2?=?Person::new; ????????//?3.使用lambda表達(dá)式,實(shí)現(xiàn)GetPersonWithMutipleParameter接口 ????????GetPersonWithMutipleParameter?getPerson3?=?Person::new; ????????System.out.println(getPerson.get()); ????????System.out.println(getPerson2.get("樹先生")); ????????System.out.println(getPerson3.get("你好",?23)); ????}}
4.對象方法的特殊引用
使用lambda表達(dá)式實(shí)現(xiàn)某些接口時(shí),如果lambda表達(dá)式中包含了某一個(gè)對象,此時(shí)方法體中,直接使用這個(gè)對象調(diào)用它的某一個(gè)方法就可以完成整體的邏輯。
/** ?*?@Description:?對象方法的特殊應(yīng)用 ?*?@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("小明");//????????邏輯實(shí)現(xiàn)只是為了獲取到對象的名字//????????MyInterface?lambda2?=?Person::getName;//????????System.out.println(lambda2.get(p1)); ???????? ????????//?邏輯實(shí)現(xiàn)只是為了給對象的某些屬性進(jìn)行賦值 ????????MyInterface?lambda1?=?(x,?n)?->?x.setName(n); ????????MyInterface?lambda2?=?Person::setName; ????????lambda2.set(p1,?"李華"); ????????System.out.println(p1.getName()); ????}}
四、Lambda表達(dá)式需要注意的問題
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.定義一個(gè)局部變量 ????????int?x?=?10; ????????//?2.使用lambda表達(dá)式實(shí)現(xiàn)接口 ????????LambdaTest?lambda?=?()?->?{ ????????????System.out.println("x="?+?x); ????????}; ????????//?3.?無法修改常量x ????????//?x=20; ????}}@FunctionalInterfaceinterface?LambdaTest?{ ????void?test();}????Im Folgenden werden 6 Arten von
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

Undress AI Tool
Ausziehbilder kostenlos

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

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

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.

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.

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

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.

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.

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.

Wie führt man eine verz?gerte Auswertung mit C++-Lambda-Ausdrücken durch? Verwenden Sie Lambda-Ausdrücke, um verz?gert ausgewertete Funktionsobjekte zu erstellen. Eine verz?gerte Berechnung verz?gert die Ausführung, bis sie ben?tigt wird. Berechnen Sie Ergebnisse nur bei Bedarf und verbessern Sie so die Leistung.
