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 Sie die 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)); }}
语法精简进阶:
三、函数引用
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: 🎜🎜🎜 🎜🎜🎜Das Folgende gilt für die oben genannten 6 A Lambda-Ausdrucksimplementierung einer funktionalen Schnittstelle. 🎜🎜rrreee🎜Erweiterte Syntaxvereinfachung: 🎜🎜🎜Der Parametertyp der Parameterliste kann weggelassen werden. 🎜Wenn die Parameterliste genau einen Parameter enthält, können die Klammern weggelassen werden. 🎜Wenn der Methodenkörper nur eine Anweisung enthält, können die geschweiften Klammern weggelassen werden. (Hinweis: Wenn es sich bei dieser Anweisung um eine Return-Anweisung handelt, sollte nach dem Weglassen der geschweiften Klammern auch das Schlüsselwort return weggelassen werden.)🎜🎜3 Funktionsreferenz🎜🎜🎜🎜Der Lambda-Ausdruck dient der Vereinfachung der Schnittstelle. In Lambda-Ausdrücken sollte keine komplexere Logik auftreten. Wenn die zu verarbeitende Logik relativ komplex ist, wird im Allgemeinen eine separate Methode geschrieben. Verweisen Sie einfach direkt im Lambda-Ausdruck auf diese Methode. Das heißt, 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!