Heim  >  Artikel  >  Java  >  Wie verwende ich Lambda-Ausdrücke in Java?

Wie verwende ich Lambda-Ausdrücke in Java?

王林
王林nach vorne
2023-04-21 20:31:141030Durchsuche

Einführung in den Lambda-Ausdruck

  • Die Essenz eines Lambda-Ausdrucks ist nur ein „Syntaxzucker“, der abgeleitet und unterstützt wird Der Compiler Sie konvertieren den Wrapper in regulären Code, sodass Sie weniger Code verwenden können, um die gleiche Funktionalität zu erreichen.

  • Lambda-Ausdrücke sind eine wichtige neue Funktion in Java SE 8.

Lambda und anonyme innere Klassen

Lamda-Ausdruck bezieht sich auf die in SAM verwendete Methode (SingleAbstractMethod, enthält Eine vereinfachte Form der Definition im Kontext einer abstrakten Methodenschnittstelle.

Vorteile von Lambda gegenüber anonymen inneren Klassen

Einfach (siehe „Funktionale Schnittstelle“ unten für Details)

Lamdas Nachteile im Vergleich zu anonymen inneren Klassen

  • Die entsprechende Schnittstelle von Lamda kann nur eine Methode haben.

  • Die der anonymen inneren Klasse entsprechende Schnittstelle kann mehrere Methoden haben

auf Schnittstellenanforderungen

1 Lambda legt fest, dass es nur eine Methode geben kann, die in der Schnittstelle implementiert werden muss (dh eine abstrakte Methode).

In einer Schnittstelle können die folgenden gleichzeitig existieren: eine abstrakte Methode (es kann nur eine geben), mehrere Standardmethoden und mehrere statische Methoden.

// Es gibt eine weitere neue Funktion in JDK 8: Die standardmäßig geänderte Methode verfügt über eine Standardimplementierung und ist keine Methode, die implementiert werden muss, sodass sie die Verwendung von Lambda nicht beeinträchtigt Ausdrücke.

2. @FunctionalInterface: Wird zum Ändern funktionaler Schnittstellen verwendet.

@FunctionalInterface Sie können es schreiben oder nicht. Diese Annotation wird hauptsächlich zur Fehlerprüfung auf Kompilierungsebene verwendet: Wenn die Schnittstelle nicht der funktionalen Schnittstellendefinition entspricht, meldet der Compiler einen Fehler.

Korrektes Beispiel, kein Fehler gemeldet:

@FunctionalInterface
public interface HelloWorldService {
    void sayHello(String msg);
}

Falsches Beispiel, Fehler gemeldet:

Die Schnittstelle enthält zwei abstrakte Methoden, die die funktionale Schnittstelle verletzen Definition: Zeigt an, dass in der Schnittstelle mehrere nicht überschriebene abstrakte Methoden gefunden wurden.

Wie verwende ich Lambda-Ausdrücke in Java?

Hinweis: Das Hinzufügen oder Nichthinzufügen von @FunctionalInterface hat keinen Einfluss darauf, ob die Schnittstelle eine funktionale Schnittstelle ist Die Schnittstelle enthält nur eine abstrakte Methode.

Variablen und Umfang

  • Lambda-Ausdrücke können nur auf äußere lokale Variablen verweisen, die als final gekennzeichnet sind. Das heißt, lokale Variablen, die außerhalb des Bereichs definiert sind, können nicht innerhalb des Lambda geändert werden, da sonst ein Kompilierungsfehler gemeldet wird (d. h. implizite endgültige Semantik)

  • Lambda-Ausdrücke dürfen keinen Parameter oder keine lokale Variable mit demselben Namen wie eine lokale Variable deklarieren.

  • Format

  • Wichtige Funktionen von Lambda-Ausdrücken

Optionale Typdeklaration: Es besteht keine Notwendigkeit, Parametertypen zu deklarieren, und der Compiler kann Parameterwerte einheitlich identifizieren.

  • Optionale Parameterklammern: Es ist nicht erforderlich, Klammern für einen Parameter zu definieren, Klammern müssen jedoch für mehrere Parameter definiert werden.

  • Optionale geschweifte Klammern: Wenn der Textkörper eine Anweisung enthält, müssen keine geschweiften Klammern verwendet werden. Beispiel: () –> gibt automatisch einen Wert zurück und die geschweiften Klammern müssen angegeben werden, um anzuzeigen, dass der Ausdruck einen Wert zurückgibt.

  • Einfaches Beispiel eines Lambda-Ausdrucks

  • 1 Es sind keine Parameter erforderlich, der Rückgabewert ist 5
  • ( ) -> 5

  • 2. Empfangen Sie einen Parameter (numerischer Typ) und geben Sie das Zweifache seines Werts zurück

x -> 2 * x

#🎜🎜 #3. Akzeptiere 2 Parameter (Zahlen) und gib ihre Differenz zurück

(x, y) -> ihre Summe

(int x, int y) -> x + y

5. Gibt keinen Wert zurück ( sieht aus, als würde void zurückgegeben)

(String s) ->

Format:

#(Parameter) -> Anweisung oder (Parameter) ->{ Anweisungen; } #🎜🎜 #

Linke Seite: Parameterliste des Lambda-Ausdrucks

Rechte Seite: Im Lambda-Ausdruck (Lambda-Körper) auszuführende Funktionen

# 🎜🎜#

Syntaxformat eins : keine Parameter, kein Rückgabewert

() -> Sysout.out.println("Test"); code><p><strong> </strong>Syntaxformat 2: Es gibt einen Parameter und keinen Rückgabewert</p> <p><strong><code>(X)-> Sysout.out .println(x);

Grammatikformat drei: Wenn eine Parameterklammer vorhanden ist, müssen Sie (parameters) -> statement   或(parameters) ->{ statements; }

左侧:Lambda 表达式的参数列表

右侧:Lambda 表达式中所需要执行的功能 (Lambda体)

语法格式一:无参数,无返回值

() -> Sysout.out.println("Test");

语法格式二:有一个参数,并且无返回值

(X)-> Sysout.out.println(x);

语法格式三:如果有一个参数括号可以不写

X-> Sysout.out.println(x);

语法格式四:有两个以上的参数,有返回值,并且Lambda体中有多条语句,语法体中需要用{}

    Comparator<Integer> comparator = (o1, o2) -> {
        System.out.println("Test");
        return Integer.compare(o1, o2);
    };

语法格式五:Lambda体中只用一条语句,return和{}可以省略不写

Comparator comparator = (o1, o2)->Integer.compare(o1, o2);

#🎜🎜#X -> nicht schreiben .out.println(x);#🎜🎜##🎜🎜##🎜🎜# Grammatikformat 4: Es gibt mehr als zwei Parameter, einen Rückgabewert und mehrere Elemente in der Lambda-Körperanweisung. Sie müssen {}#🎜🎜##🎜🎜#
package org.example.a;
 
@FunctionalInterface
interface Interface {
    void run();
}
 
public class Demo{
    public static void main(String[] args) {
        Interface params = new Interface() {
            @Override
            public void run() {
                System.out.println("Anonymous Internal Class: ");
            }
        };
 
        Interface params1 = () -> System.out.println("Lambda: ");
 
        params.run();
        params1.run();
    }
}
#🎜🎜##🎜🎜# im Grammatikformat 5 verwenden: Im Lambda-Körper wird nur eine Anweisung verwendet, return und {} können weggelassen werden #. 🎜🎜# #🎜🎜##🎜🎜#Comparator comparator = (o1, o2)->Integer.compare(o1, o2);#🎜🎜#

语法格式六:表达式的参数列表的数据类型可以省略不写,JVM编译器通过上下文推断出数据类型

(x ,y ) ->Integer.compare(x ,y)

实例

无参数无返回值

package org.example.a;
 
@FunctionalInterface
interface Interface {
    void run();
}
 
public class Demo{
    public static void main(String[] args) {
        Interface params = new Interface() {
            @Override
            public void run() {
                System.out.println("Anonymous Internal Class: ");
            }
        };
 
        Interface params1 = () -> System.out.println("Lambda: ");
 
        params.run();
        params1.run();
    }
}

执行结果

Anonymous Internal Class: 
Lambda: 

有参数无返回值

package org.example.a;
 
@FunctionalInterface
interface Interface {
    void run(String s);
}
 
public class Demo{
    public static void main(String[] args) {
        Interface params = new Interface() {
            @Override
            public void run(String s) {
                System.out.println("Anonymous Internal Class: " + s);
            }
        };
 
        Interface params1 = (s) -> System.out.println("Lambda: " + s);
 
        params.run("hello");
        params1.run("hi");
    }
}

执行结果

Anonymous Internal Class: hello
Lambda: hi 

有参数有返回值

package org.example.a;
 
@FunctionalInterface
interface Interface {
    String run(String s);
}
 
public class Demo{
    public static void main(String[] args) {
        Interface params = new Interface() {
            @Override
            public String run(String s) {
                System.out.println("Anonymous Internal Class: " + s);
                return "abc";
            }
        };
 
        Interface params1 = (s) -> {
            System.out.println("Lambda: " + s);
            return "def";
        };
 
        System.out.println(params.run("hello"));
        System.out.println(params1.run("hi"));
    }
}

执行结果

Anonymous Internal Class: hello
abc
Lambda: hi
def 

lambda作为参数

传递一个函数

package org.example.a;
 
interface IRun {
    String welcome(String string);
}
 
class Util {
    public static long executionTime1(IRun iRun, String string) {
        long startTime = System.currentTimeMillis();
        System.out.println(iRun.welcome(string));
        //本处刻意添加这一无意义延时,防止执行太快返回0
        try {
            Thread.sleep(10);
        } catch (Exception e) {
            System.out.println(e);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }
 
    public long executionTime2(IRun iRun, String string) {
        long startTime = System.currentTimeMillis();
        System.out.println(iRun.welcome(string));
        //本处刻意添加这一无意义延时,防止执行太快返回0
        try {
            Thread.sleep(10);
        } catch (Exception e) {
            System.out.println(e);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }
 
    public static String hello(String string){
        String tmp;
        tmp = "hello: " + string;
        return tmp;
    }
 
    public String hi(String string){
        String tmp;
        tmp = "hi: " + string;
        return tmp;
    }
}
 
public class Demo {
    public static void main(String[] args) {
        long time1 = Util.executionTime1(Util::hello, "Tony");
        long time2 = new Util().executionTime2(new Util()::hi, "Pepper");
        System.out.println("time1: " + time1 + "ms");
        System.out.println("time2: " + time2 + "ms");
    }
}

执行结果

hello: Tony
hi: Pepper
time1: 11ms
time2: 11ms

直接传递lambda函数 

package org.example.a;
 
interface IRun {
    String welcome(String string);
}
 
class Util {
    public static long executionTime(IRun iRun, String string) {
        long startTime = System.currentTimeMillis();
        System.out.println(iRun.welcome(string));
        //本处刻意添加这一无意义延时,防止执行太快返回0
        try {
            Thread.sleep(10);
        } catch (Exception e) {
            System.out.println(e);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }
}
 
public class Demo {
    public static void main(String[] args) {
        long time = Util.executionTime((string -> {
                    String tmp;
                    tmp = "hello: " + string;
                    return tmp;
                })
                , "Tony");
        System.out.println("time: " + time + "ms");
    }
}

执行结果

hello: Tony
time: 11ms

遍历集合

package org.example.a;
 
import java.util.ArrayList;
import java.util.List;
 
public class Demo{
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
 
        //以前的循环方式
        for (String string : list) {
            System.out.println(string);
        }
 
        //使用lambda表达式输出list中的每个值
        list.forEach(c->{
            System.out.println(c);
        });
 
        // 在 Java 8 中使用双冒号操作符(double colon operator)。也属于lamda表达式
        list.forEach(System.out::println);
    }
}

执行结果

aaa
bbb
aaa
bbb
aaa
bbb

创建线程

package org.example.a;
 
public class Demo{
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Anonymous Internal Class !");
            }
        }).start();
 
        new Thread(() -> System.out.println("Lambda !")).start();
    }
}

执行结果

Anonymous Internal Class !
Lambda !

排序

package org.example.a;
 
import java.util.Arrays;
import java.util.Comparator;
 
public class Demo{
    public static void main(String[] args) {
        String[] players = {"Rafael Nadal", "Novak Djokovic", "Stanislas Wawrinka"};
        
        Arrays.sort(players, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return (o1.compareTo(o2));
            }
        });
 
//        Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
//        Arrays.sort(players, sortByName);
        
//        Arrays.sort(players, (String s1, String s2) -> (s1.compareTo(s2)));
        
        for(String string:players){
            System.out.println(string);
        }
    }
}

执行结果(换成注释掉的两种任意一种都是一样的)

Novak Djokovic
Rafael Nadal
Stanislas Wawrinka

Das obige ist der detaillierte Inhalt vonWie verwende ich Lambda-Ausdrücke in Java?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen