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); }
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.
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.
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); };
语法格式五:Lambda体中只用一条语句,return和{}可以省略不写
Comparator comparator = (o1, o2)->Integer.compare(o1, o2);
() -> Sysout.out.println("Test");
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(); } }🎜🎜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(); } }
执行结果
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
传递一个函数
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
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!