Maison  >  Article  >  Java  >  Quelles sont les méthodes utilisées dans les expressions Lambda en Java

Quelles sont les méthodes utilisées dans les expressions Lambda en Java

WBOY
WBOYavant
2023-06-03 16:55:541180parcourir

    1. Introduction aux expressions Lambda

    Expression Lambda (fermeture) : une nouvelle fonctionnalité de java8, l'opération lambda utilise une fonction comme paramètre d'une méthode, c'est-à-dire que la fonction est passée dans la méthode en tant que paramètre . L'utilisation d'expressions lambda peut rendre votre code plus concis.

    Scénarios d'utilisation des expressions Lambda : utilisées pour simplifier la mise en œuvre de l'interface.

    Concernant l'implémentation de l'interface, il existe de nombreuses façons de la mettre en œuvre. Par exemple : concevez la classe d’implémentation de l’interface et utilisez des classes internes anonymes. Mais les expressions lambda sont plus simples que ces deux méthodes.

    package test;
    /**
     * @author: Mercury
     * Date: 2022/3/20
     * Time: 17:48
     * Description:Lambda表达式
     * Version:1.0
     */
    public class Test04 {
        public static void main(String[] args) {
            //使用lambda表达式实现接口
            Test test = () -> {
                System.out.println("test");
            };
            test.test();
        }
    }
    interface Test{
        public void test();
    }

    2. Exigences des expressions Lambda sur les interfaces

    Bien que les expressions lambda puissent simplifier dans une certaine mesure la mise en œuvre des interfaces. Cependant, toutes les interfaces ne peuvent pas être implémentées de manière concise à l'aide d'expressions lambda.

    l'expression lambda n'est qu'une méthode anonyme après tout. Les expressions Lambda ne sont pas applicables lorsque l'interface implémentée comporte trop ou trop de méthodes.

    Les expressions Lambda ne peuvent implémenter que des interfaces fonctionnelles.

    1. Interface fonctionnelle

    Si on dit que dans une interface, il n'y a qu'une seule méthode abstraite que la classe implémentante doit implémenter ! Une telle interface est une interface fonctionnelle.

    Le code est le suivant (exemple) :

    //有且只有一个实现类必须要实现的抽象方法,所以是函数式接口
    interface Test{
        public void test();
    }

    2.@FunctionalInterface

    est une annotation, utilisée avant une interface pour déterminer si l'interface est une interface fonctionnelle. S'il s'agit d'une interface fonctionnelle, il n'y a pas de problème. S'il ne s'agit pas d'une interface fonctionnelle, une erreur sera signalée. Fonction similaire à @Override.
    Le code est le suivant (exemple) :

    @FunctionalInterface
    interface Test{
        public void test();
    }

    3. La syntaxe de l'expression Lambda

    1 La syntaxe de base de l'expression Lambda

    Une expression lambda, par essence, est une fonction anonyme. Par conséquent, lorsque vous écrivez des expressions lambda, vous n'avez pas besoin de vous soucier du nom de la méthode.

    En fait, lorsque nous écrivons des expressions lambda, nous n'avons pas besoin de nous soucier du type de valeur de retour.

    Lorsque nous écrivons des expressions lambda, nous ne devons prêter attention qu'à deux parties : la liste des paramètres et le corps de la méthode

    Syntaxe de base des expressions lambda :
    (paramètre 1, paramètre 2,…) -> };

    Partie paramètre : la liste des paramètres de la méthode doit être cohérente avec la partie paramètre de la méthode dans l'interface implémentée, y compris le nombre et le type de paramètres.

    Partie corps de la méthode : la partie implémentation de la méthode. Si la méthode définie dans l'interface a une valeur de retour, faites attention à la valeur de retour lors de son implémentation.

    -> : Séparez la partie paramètre et la partie corps de la méthode.

    Exemple de code :

    package test;
    /**
     * @author: Mercury
     * Date: 2022/3/20
     * Time: 17:48
     * Description:Lambda表达式
     * Version:1.0
     */
    public class Test04 {
        public static void main(String[] args) {
            //使用lambda表达式实现接口
            //无参
    //        Test test = () -> {
    //            System.out.println("test");
    //        };
            //有参
    //        Test test = (name,age) -> {
    //            System.out.println(name+age+"岁了!");
    //        };
    //        test.test("小新",18);
            //有参+返回值
            Test test = (name,age)  -> {
                System.out.println(name+age+"岁了!");
                return age + 1;
            };
            int age = test.test("小新",18);
            System.out.println(age);
        }
    }
    //无参
    //interface Test{
    //    public void test();
    //}
    //有参 无返回值
    //interface Test{
    //    public void test(String name,int age);
    //}
    //有参 有返回值
    interface Test{
        public int test(String name,int age);
    }

    4. Avancement de la syntaxe des expressions Lambda

    Simplification de la partie paramètre

    Types de paramètres

    Car dans la méthode d'interface, le type de chaque paramètre a été défini . Et lorsque vous utilisez des expressions lambda pour implémenter des interfaces, vous devez vous assurer que le nombre et le type de paramètres sont cohérents avec les méthodes de l'interface. Par conséquent, le type de paramètres dans l’expression lambda peut être omis pour le moment.

    Remarque :

    Si vous devez omettre le type de paramètre, assurez-vous : Si vous souhaitez l'omettre, le type de chaque paramètre doit être omis. Il ne doit pas apparaître. Certains types de paramètres sont omis et certains types de paramètres ne sont pas omis.

            //有参+返回值
            Test test = (name,age)  -> {
                System.out.println(name+age+"岁了!");
                return age + 1;
            };
            int age = test.test("小新",18);
            System.out.println(age);

    Parenthèses pour les paramètres

    S'il y a et n'est qu'un seul paramètre dans la liste des paramètres de la méthode, à ce moment, les parenthèses de la liste des paramètres peuvent être omises.

    Remarque :

      Seulement lorsque le nombre de paramètres est un, plus ou moins ne peut pas être omis.
    • Lors de l'omission des parenthèses, le type du paramètre doit être omis
    •         //一个参数
              Test test = name -> {
                  System.out.println(name+"test");
              };
              test.test("小新");
    Simplification de la partie du corps de la méthode

    Simplification des parenthèses du corps de la méthode

    Lorsque la logique dans un corps de méthode a et Lorsqu'il n'y a qu'une seule phrase, les accolades peuvent être omises

    Test test = name -> System.out.println(name+"test");
            test.test("小新");

    Simplification du retour

    Si la seule instruction d'une méthode est une instruction return, en omettant les accolades, elle doit également omettre return.

    Test test = (a,b) -> a+b;

    3. Référence de fonction

    L'expression lambda vise à simplifier la mise en œuvre de l'interface. Dans les expressions lambda, aucune logique plus complexe ne devrait apparaître. L'utilisation d'une logique trop complexe dans les expressions lambda affectera grandement la lisibilité du programme. Normalement, si une expression lambda doit gérer une logique complexe, nous écrirons une méthode distincte pour la gérer. Référencez simplement cette méthode directement dans l’expression lambda.

    Référence de fonction

    : Référencez une méthode existante pour remplacer l'expression lambda pour terminer l'implémentation de l'interface1 Référence de la méthode statique

    Syntaxe

    : Classe :: méthode statique

    Remarques :

    .

      N'ajoutez pas de parenthèses après la méthode référencée.
    • La méthode référencée, les paramètres (numéro, type) et la valeur de retour doivent être cohérents avec ceux définis dans l'interface
    • package test;
      /**
       * @author: Mercury
       * Date: 2022/3/20
       * Time: 18:17
       * Description:lambda表达式静态方法引用
       * Version:1.0
       */
      public class Test05 {
          public static void main(String[] args) {
              //实现多个参数,一个返回值的接口
              //对一个静态方法的引用,语法:类::静态方法
              Test1 test1 = Calculator::calculate;
              System.out.println(test1.test(4,5));
          }
      }
      class Calculator{
          public static int calculate(int a,int b ){
              // 稍微复杂的逻辑:计算a和b的差值的绝对值
              if (a > b) {
                  return a - b;
              }
              return b - a;
          }
      }
      interface Test1{
          int test(int a,int b);
      }
      package test;
      /**
       * @author: Mercury
       * Date: 2022/3/20
       * Time: 18:17
       * Description:lambda表达式静态方法引用
       * Version:1.0
       */
      public class Test05 {
          public static void main(String[] args) {
              //实现多个参数,一个返回值的接口
              //对一个静态方法的引用,语法:类::静态方法
              Test1 test1 = Calculator::calculate;
              System.out.println(test1.test(4,5));
          }
      }
      class Calculator{
          public static int calculate(int a,int b ){
              // 稍微复杂的逻辑:计算a和b的差值的绝对值
              if (a > b) {
                  return a - b;
              }
              return b - a;
          }
      }
      interface Test1{
          int test(int a,int b);
      }
    • 2 Référence aux méthodes non statiques

    Syntaxe

    : Objet :: non statique. méthodes

    Notes

     :

      Après la méthode référencée, n'ajoutez pas de parenthèses.
    • 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的⼀致。

    package test;
    /**
     * @author: Mercury
     * Date: 2022/3/21
     * Time: 8:14
     * Description:lambda表达式对非静态方法的引用
     * Version:1.0
     */
    public class Test06 {
        public static void main(String[] args) {
            //对非静态方法的引用,需要使用对象来完成
            Test2 test2 = new Calculator()::calculate;
            System.out.println(test2.calculate(2, 3));
        }
        private static class Calculator{
            public int calculate(int a, int b) {
                return a > b ? a - b : b - a;
             }
        }
    }
    interface Test2{
        int calculate(int a,int b);
    }

    3.构造方法的引用

    使用场景

    如果某个函数式接口中所定义的方法只是为了获取一个类的对象。此时我们就可以使用构造方法的引用,简化这个方法的实现。

    语法:类名::new

    注意事项:可以通过接口中的方法的参数, 区分引用不同的构造方法。

    package com.cq.test;
    /**
     * @author: Mercury
     * Date: 2022/4/27
     * Time: 10:31
     * Description:lambda构造方法的引用
     * Version:1.0
     */
    public class Test {
        private static class Dog{
            String name;
            int age;
            //无参构造
            public Dog(){
                System.out.println("一个Dog对象通过无参构造被实例化了");
            }
            //有参构造
            public Dog(String name,int age){
                System.out.println("一个Dog对象通过有参构造被实例化了");
                this.name = name;
                this.age = age;
            }
        }
        //定义一个函数式接口,用以获取无参的对象
        @FunctionalInterface
        private interface GetDog{
            //若此方法仅仅是为了获得一个Dog对象,而且通过无参构造去获取一个Dog对象作为返回值
            Dog test();
        }
        //定义一个函数式接口,用以获取有参的对象
        @FunctionalInterface
        private interface GetDogWithParameter{
            //若此方法仅仅是为了获得一个Dog对象,而且通过有参构造去获取一个Dog对象作为返回值
            Dog test(String name,int age);
        }
        // 测试
        public static void main(String[] args) {
            //lambda表达式实现接口
            GetDog lm = Dog::new; //引用到Dog类中的无参构造方法,获取到一个Dog对象
            Dog dog = lm.test();
            System.out.println("修狗的名字:"+dog.name+" 修狗的年龄:"+dog.age); //修狗的名字:null 修狗的年龄:0
            GetDogWithParameter lm2 = Dog::new;//引用到Dog类中的有参构造,来获取一个Dog对象
            Dog dog1 = lm2.test("萨摩耶",2);
            System.out.println("修狗的名字:"+dog1.name+" 修狗的年龄:"+dog1.age);//修狗的名字:萨摩耶 修狗的年龄:2
        }
    }

    四、Lambda表达式需要注意的问题

    这⾥类似于局部内部类、匿名内部类,依然存在闭包的问题。

    如果在lambda表达式中引用了局部变量,则该局部变量会隐式声明为final变量。是⼀个常量,不能修改值。

    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!

    Déclaration:
    Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer