Rumah >Java >javaTutorial >Apakah kaedah yang digunakan dalam ungkapan Lambda di Jawa

Apakah kaedah yang digunakan dalam ungkapan Lambda di Jawa

WBOY
WBOYke hadapan
2023-06-03 16:55:541218semak imbas

    1 Pengenalan kepada ungkapan Lambda

    Ungkapan Lambda (penutupan): ciri baharu java8, operasi lambda menggunakan fungsi sebagai parameter kaedah , iaitu, fungsi disalurkan ke dalam kaedah sebagai parameter. Menggunakan ungkapan lambda boleh menjadikan kod anda lebih ringkas.

    Senario penggunaan ungkapan Lambda: digunakan untuk memudahkan pelaksanaan antara muka.

    Mengenai pelaksanaan antara muka, terdapat banyak cara untuk melaksanakannya. Contohnya: reka bentuk kelas pelaksanaan antara muka dan gunakan kelas dalaman tanpa nama. Tetapi ungkapan lambda adalah lebih mudah daripada kedua-dua kaedah ini.

    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. Keperluan ungkapan Lambda pada antara muka

    Walaupun, ungkapan lambda boleh memudahkan pelaksanaan antara muka pada tahap tertentu. Walau bagaimanapun, tidak semua antara muka boleh dilaksanakan secara ringkas menggunakan ungkapan lambda.

    Ungkapan lambda hanyalah kaedah tanpa nama. Ungkapan Lambda tidak boleh digunakan apabila antara muka yang dilaksanakan mempunyai terlalu banyak atau terlalu banyak kaedah.

    Ekspresi Lambda hanya boleh melaksanakan antara muka berfungsi.

    1. Antara muka berfungsi

    Jika kita katakan bahawa dalam antara muka, terdapat hanya satu kaedah abstrak yang mesti dilaksanakan oleh kelas pelaksanaan! Antara muka sedemikian adalah antara muka berfungsi.

    Kod adalah seperti berikut (contoh):

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

    2.@FunctionalInterface

    ialah anotasi, digunakan sebelum antara muka untuk menentukan sama ada antara muka ialah ⼼Satu antara muka berfungsi. Jika ia adalah antara muka yang berfungsi, tiada masalah. Jika ia bukan antara muka berfungsi, ralat akan dilaporkan. Fungsi serupa dengan @Override.
    Kod adalah seperti berikut (contoh):

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

    3. Sintaks ungkapan Lambda

    1. ungkapan sebenarnya Dalam erti kata lain, ia adalah fungsi tanpa nama. Oleh itu, apabila menulis ungkapan lambda, anda tidak perlu mengambil berat tentang nama kaedah.

    Sebenarnya, apabila kita menulis ungkapan lambda, kita tidak perlu mengambil berat tentang jenis nilai pulangan.

    Apabila kita menulis ungkapan lambda, kita hanya perlu memberi perhatian kepada dua bahagian: senarai parameter dan badan kaedah

    Sintaks asas ungkapan lambda:

    (parameter 1, parameter 2,. .. dan taip.


    Bahagian badan kaedah: Bahagian pelaksanaan kaedah Jika kaedah yang ditakrifkan dalam antara muka mempunyai nilai pulangan, perhatikan nilai pulangan apabila melaksanakannya.

    -> : Mengasingkan bahagian parameter dan bahagian badan kaedah.

    Contoh kod:

    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. Kemajuan sintaks ungkapan Lambda

    Pemudahan bahagian parameter

    Jenis parameter

    Kerana dalam kaedah antara muka, jenis setiap parameter telah ditentukan. Dan apabila menggunakan ungkapan lambda untuk melaksanakan antara muka, anda mesti memastikan bahawa bilangan dan jenis parameter adalah konsisten dengan kaedah dalam antara muka. Oleh itu, jenis parameter dalam ungkapan lambda boleh ditinggalkan pada masa ini.

    Nota:

    Jika anda perlu meninggalkan jenis parameter, pastikan: jika anda ingin meninggalkannya, jenis setiap parameter mesti ditinggalkan. Ia mesti tidak muncul Beberapa jenis parameter ditinggalkan, dan beberapa jenis parameter tidak ditinggalkan.

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

    Kurungan untuk parameter

    Jika terdapat dan hanya satu parameter dalam senarai parameter kaedah, pada masa ini, kurungan senarai parameter boleh ditinggalkan.

    Nota:

    Hanya apabila bilangan parameter adalah satu, lebih atau kurang tidak boleh ditinggalkan.

      Apabila meninggalkan kurungan, jenis parameter mesti ditinggalkan
    •         //一个参数
              Test test = name -> {
                  System.out.println(name+"test");
              };
              test.test("小新");
    • Pemudahan bahagian badan kaedah

    • Pemudahan kurungan besar dalam badan kaedah

    Apabila logik dalam badan kaedah mempunyai satu dan hanya satu ayat, kurungan besar boleh ditinggalkan

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

    kembali Penyederhanaan

    Jika satu-satunya pernyataan dalam kaedah ialah pernyataan pulangan, apabila menghilangkan kurung kerinting, pulangan juga mesti ditinggalkan.

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

    3. Rujukan fungsiEkspresi Lambda adalah untuk memudahkan pelaksanaan antara muka. Dalam ungkapan lambda, logik yang lebih kompleks tidak sepatutnya muncul. Penggunaan logik yang terlalu kompleks dalam ungkapan lambda akan sangat mempengaruhi kebolehbacaan atur cara. Biasanya, jika ungkapan lambda perlu mengendalikan logik yang kompleks, kami akan menulis kaedah berasingan untuk mengendalikannya. Hanya rujuk kaedah ini secara langsung dalam ungkapan lambda.

    Rujukan fungsi

    : Rujukan kaedah sedia ada untuk menggantikan ungkapan lambda untuk melengkapkan pelaksanaan antara muka

    1 Rujukan kepada kaedah statik

    Sintaks: kelas::kaedah statik

    Nota:

    Selepas kaedah yang dirujuk, jangan tambah kurungan kecil.

      Parameter (nombor, jenis) dan nilai pulangan kaedah yang dirujuk mestilah konsisten dengan yang ditakrifkan dalam antara muka
    • 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 . Rujukan kaedah bukan statik
    • Sintaksis
    • : Objek::Kaedah bukan statik

    Nota

    :

    Jangan tambah kurungan selepas kaedah yang dirujuk.

  • 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的⼀致。

  • 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变量。是⼀个常量,不能修改值。

    Atas ialah kandungan terperinci Apakah kaedah yang digunakan dalam ungkapan Lambda di Jawa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam