Heim > Java > JavaBase > Hauptteil

Einführung in Lambda-Ausdrücke, den syntaktischen Zucker von Java 8

coldplay.xixi
Freigeben: 2021-02-18 18:09:05
nach vorne
2842 Leute haben es durchsucht

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 Sie die Methoden in der Schnittstelle implementieren. 匿名方法。可以使用这个匿名方法,实现接口中的方法

  • 功能:通常使用Lambda表达式,是为了简化接口实现的。关于接口实现可以有多种方式实现,例如:①设计接口的实现类、②使用匿名内部类。但是③使用lambda表达式,比这两种方式都简单。

  • 要求:lambda表达式,只能实现函数式接口:即一个接口中,要求实现类必须实现的抽象方法,有且只有一个。

@FunctionalInterface注解 ,用在接口之前,用来判断接口是否是一个函数式接口。如果不是函数式接口会报错。功能类似于@Override。

二、Lambda表达式语法

lambda表达式本质上是一个匿名方法,因此再写lambda表达式时,不需要关心方法名是什么,也不需要关心返回值类型。只需要关心两部分:参数列表方法体

  • ()参数部分:方法的参数列表,要求和实现的接口中的方法参数部分一致,包括参数的数量和类型。
  • {}方法体部分:方法的实现部分,如果接口中定义的方法有返回值,则在实现时,注意返回值的返回。
  • -> :分隔参数部分和方法体部分。
Lambda表达式基础语法:(参数) ->{
	方法体}
Nach dem Login kopieren

下面定义6种参数和返回值各不相同的函数式接口,分别使用lambda表达式对接口中的方法进行实现:

Einführung in Lambda-Ausdrücke, den syntaktischen Zucker von Java 8

下面是针对上面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));
    }}
Nach dem Login kopieren

语法精简进阶:

  • 参数列表的参数类型可以省略。
  • 如果参数列表中的参数有且只有一个,可以省略小括号。
  • 如果方法体中只有一条语句,可以省略大括号。(注:如果这条语句是返回语句,省略了大括号后也要把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));
    }}
Nach dem Login kopieren

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));
    }}
Nach dem Login kopieren

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());
    }}
Nach dem Login kopieren

四、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.

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.

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: 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();}
Nach dem Login kopieren
🎜🎜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: 🎜🎜🎜 Bildbeschreibung hier einfügen🎜🎜🎜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!

Verwandte Etiketten:
Quelle:csdn.net
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage