Maison > Java > javaDidacticiel > le corps du texte

Comment utiliser les expressions Lambda en Java ?

王林
Libérer: 2023-04-21 20:31:14
avant
1015 Les gens l'ont consulté

Introduction aux expressions Lambda

  • L'essence de l'expression Lambda est juste un "sucre de syntaxe", qui est déduit par le compilateur et vous aide à le convertir et à l'envelopper dans du code normal, afin que vous puissiez utiliser moins de code pour atteindre l'objectif. même fonction.

  • Les expressions Lambda sont une nouvelle fonctionnalité importante de Java SE 8.

Classes internes Lambda et anonymes

L'expression Lamda fait référence à une forme de définition simplifiée appliquée dans l'environnement SAM (SingleAbstractMethod, interface contenant une méthode abstraite).

Avantages de Lambda par rapport aux classes internes anonymes

Simple (voir "Interface fonctionnelle" ci-dessous pour plus de détails)

Inconvénients de Lamda par rapport aux classes internes anonymes

  • L'interface correspondante de Lamda ne peut avoir qu'une seule méthode.

  • L'interface correspondant à la classe interne anonyme peut avoir plusieurs méthodes

Exigences pour l'interface

1. Lambda stipule qu'il ne peut y avoir qu'une seule méthode qui doit être implémentée dans l'interface (c'est-à-dire abstraite. méthode).

Dans une interface, les méthodes suivantes peuvent exister en même temps : une méthode abstraite (il ne peut y en avoir qu'une), plusieurs méthodes par défaut et plusieurs méthodes statiques.

// Il y a une autre nouveauté dans jdk 8 : default. La méthode modifiée par défaut aura une implémentation par défaut et n'est pas une méthode qui doit être implémentée, elle n'affecte donc pas l'utilisation des expressions Lambda.

2.@FunctionalInterface : Utilisé pour modifier les interfaces fonctionnelles.

@FunctionalInterface peut être écrit ou non. Cette annotation est principalement utilisée pour la vérification des erreurs au niveau de la compilation : lorsque l'interface n'est pas conforme à la définition de l'interface fonctionnelle, le compilateur signalera une erreur.

Exemple correct, aucune erreur signalée :

@FunctionalInterface
public interface HelloWorldService {
    void sayHello(String msg);
}
Copier après la connexion

Exemple incorrect, erreur signalée :

L'interface contient deux méthodes abstraites, ce qui viole la définition de l'interface fonctionnelle, indiquant que plusieurs méthodes abstraites non remplacées ont été trouvées dans l'interface.

Comment utiliser les expressions Lambda en Java ?

Remarque : L'ajout ou non de @FunctionalInterface n'a aucun effet sur le fait que l'interface soit une interface fonctionnelle. Cette annotation rappelle simplement au compilateur de vérifier si l'interface ne contient qu'une seule méthode abstraite.

Variables et portée

  • Les expressions Lambda ne peuvent faire référence qu'à des variables locales externes marquées comme finale. C'est-à-dire que les variables locales définies en dehors de la portée ne peuvent pas être modifiées à l'intérieur du lambda, sinon une erreur de compilation sera signalée

  • Les variables locales de l'expression Lambda n'ont pas besoin d'être déclarées finales, mais elles ne doivent pas être modifiées par les suivantes. code (c'est-à-dire qu'ils ont une sémantique finale implicite)

  • Les expressions lambda ne sont pas autorisées à déclarer un paramètre ou une variable locale avec le même nom qu'une variable locale.

Format

Caractéristiques importantes des expressions lambda

  • Déclaration de type facultative : il n'est pas nécessaire de déclarer les types de paramètres, le compilateur peut identifier uniformément les valeurs des paramètres.

  • Parenthèses de paramètres facultatives : il n'est pas nécessaire de définir des parenthèses pour un paramètre, mais plusieurs paramètres doivent définir des parenthèses.

  • Accolades facultatives : Si le corps contient une déclaration, il n'est pas nécessaire d'utiliser des accolades. Exemple : () -> Sysout.out.println("Test");

  • Mot-clé de retour facultatif : si le corps n'a qu'une seule valeur de retour d'expression, le compilateur renverra automatiquement la valeur et les accolades doivent être spécifiées clairement L'expression a renvoyé une valeur numérique.

Un exemple simple d'expression Lambda

1. Aucun paramètre n'est requis, la valeur de retour est 5

() -> 5

2.

x -> 2 * x

3. Accepte 2 paramètres (nombres) et renvoie leur différence

(x, y) -> x – (int x, int y) -> s) -> System.out.print(s)

Format de syntaxe

Format :

(paramètres) -> ) ->{ déclarations; }</ code><p><strong>Côté gauche : la liste des paramètres de l'expression Lambda</strong></p>Côté droit : la fonction à exécuter dans l'expression Lambda (corps Lambda)<p><strong></strong>Format de syntaxe un : non paramètres, pas de valeur de retour</p><p><code>(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);
    };
Copier après la connexion

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

Comparator comparator = (o1, o2)->Integer.compare(o1, o2); () -> Sysout.out.println("Test");

🎜🎜Format de syntaxe 2 : Il y a un paramètre et aucune valeur de retour🎜🎜🎜< code>(X)-> Sysout.out .println(x);🎜🎜🎜Format de grammaire trois : s'il y a un crochet de paramètre, vous n'avez pas besoin de l'écrire🎜🎜🎜X -> Sysout.out.println(x);🎜🎜 🎜Format de grammaire 4 : il y a plus de deux paramètres, une valeur de retour et plusieurs instructions dans le corps Lambda {} sont requises. corps grammatical🎜🎜
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();
    }
}
Copier après la connexion
Copier après la connexion
🎜🎜Format de grammaire 5 : une seule instruction est utilisée dans le corps Lambda, return et {} peuvent être omis🎜🎜🎜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();
    }
}
Copier après la connexion
Copier après la connexion

执行结果

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");
    }
}
Copier après la connexion

执行结果

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"));
    }
}
Copier après la connexion

执行结果

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");
    }
}
Copier après la connexion

执行结果

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");
    }
}
Copier après la connexion

执行结果

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);
    }
}
Copier après la connexion

执行结果

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();
    }
}
Copier après la connexion

执行结果

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);
        }
    }
}
Copier après la connexion

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

Novak Djokovic
Rafael Nadal
Stanislas Wawrinka

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!