>  기사  >  Java  >  Java의 Lambda 표현식에 사용되는 메소드는 무엇입니까?

Java의 Lambda 표현식에 사용되는 메소드는 무엇입니까?

WBOY
WBOY앞으로
2023-06-03 16:55:541136검색

    1. 람다 표현식 소개

    람다 표현식(클로저): java8의 새로운 기능인 람다 연산은 함수를 메소드의 매개변수로 사용합니다. 즉, 함수가 매개변수로 메소드에 전달됩니다. . 람다 식을 사용하면 코드를 더 간결하게 만들 수 있습니다.

    람다 표현식의 사용 시나리오: 인터페이스 구현을 단순화하는 데 사용됩니다.

    인터페이스 구현과 관련하여 구현하는 방법에는 여러 가지가 있습니다. 예를 들어 인터페이스의 구현 클래스를 디자인하고 익명 내부 클래스를 사용합니다. 그러나 람다 표현식은 이 두 가지 방법보다 더 간단합니다.

    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. 인터페이스에서 람다 표현식의 요구 사항

    하지만 람다 표현식은 인터페이스 구현을 어느 정도 단순화할 수 있습니다. 그러나 람다 식을 사용하여 모든 인터페이스를 간결하게 구현할 수 있는 것은 아닙니다.

    lambda 표현식은 결국 익명 메서드일 뿐입니다. 구현된 인터페이스에 메서드가 너무 많거나 너무 많으면 람다 식을 적용할 수 없습니다.

    Lambda 표현식은 기능적 인터페이스만 구현할 수 있습니다.

    1. 기능적 인터페이스

    인터페이스에서 구현 클래스가 구현해야 하는 추상 메소드는 단 하나뿐입니다! 이러한 인터페이스는 기능적 인터페이스입니다.

    코드는 다음과 같습니다(예).

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

    2.@FunctionalInterface

    는 인터페이스 앞에 사용되는 주석으로 해당 인터페이스가 기능적 인터페이스인지 여부를 확인하는 데 사용됩니다. 기능적인 인터페이스라면 문제가 없습니다. 기능적 인터페이스가 아닌 경우 오류가 보고됩니다. @Override와 유사한 기능입니다.
    코드는 다음과 같습니다(예).

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

    3. 람다 표현식의 구문

    1. 람다 표현식의 기본 구문

    람다 표현식은 본질적으로 익명 함수입니다. 따라서 람다 식을 작성할 때 메서드 이름에 신경 쓸 필요가 없습니다.

    사실 람다 표현식을 작성할 때 반환 값 유형에 신경 쓸 필요가 없습니다.

    람다 표현식을 작성할 때 매개변수 목록과 메소드 본문 두 부분에만 주의하면 됩니다.

    람다 표현식의 기본 구문:
    (매개변수 1, 매개변수 2, …) -> };

    매개변수 부분: 메소드의 매개변수 목록은 매개변수의 수와 유형을 포함하여 구현된 인터페이스의 메소드 매개변수 부분과 일치해야 합니다.

    메서드 본문 부분: 메소드의 구현 부분입니다. 인터페이스에 정의된 메소드에 반환 값이 있는 경우 구현 시 반환 값에 주의하세요.

    -> : 매개변수 부분과 메소드 본문 부분을 분리합니다.

    코드예시:

    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. 람다식의 구문고급화

    파라미터 부분의 단순화

    파라미터의 종류

    인터페이스 메소드에서 각 파라미터의 타입이 정의되어 있기 때문입니다. 그리고 람다 식을 사용하여 인터페이스를 구현할 때는 매개 변수의 수와 유형이 인터페이스의 메서드와 일치하는지 확인해야 합니다. 따라서 이때 람다 식의 매개 변수 형식은 생략할 수 있습니다.

    참고:

    매개변수 유형을 생략해야 하는 경우 다음을 확인하세요. 이를 생략하려면 각 매개변수의 유형을 생략해야 합니다. 나타나서는 안 됩니다. 일부 매개변수 유형은 생략되고 일부 매개변수 유형은 생략되지 않습니다.

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

    매개변수에 대한 괄호

    메소드의 매개변수 목록에 매개변수가 1개뿐인 경우, 이때 매개변수 목록의 괄호는 생략 가능합니다.

    참고:

      매개변수 개수가 1개인 경우에만 그 이상 또는 그 이하를 생략할 수 없습니다.
    • 괄호 생략 시 매개변수의 타입도 생략해야 합니다
    •         //一个参数
              Test test = name -> {
                  System.out.println(name+"test");
              };
              test.test("小新");
    메소드 본문 부분 단순화

    메서드 본문 괄호 단순화

    메서드 본문의 로직이 다음과 같은 경우 그리고 문장이 하나뿐인 경우 중괄호는 생략 가능

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

    return 단순화

    메서드의 유일한 명령문이 return 문이라면 이때 중괄호를 생략하면서 return도 생략해야 합니다. .

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

    3. 함수 참조

    lambda 표현식은 인터페이스 구현을 단순화하기 위한 것입니다. 람다 식에서는 더 복잡한 논리가 나타나서는 안 됩니다. 람다 식에 지나치게 복잡한 논리를 사용하면 프로그램의 가독성에 큰 영향을 미칩니다. 일반적으로 람다 표현식이 복잡한 논리를 처리해야 하는 경우 이를 처리하기 위한 별도의 메서드를 작성합니다. 람다 식에서 이 메서드를 직접 참조하면 됩니다.

    함수 참조

    : 기존 메서드를 참조하여 람다 식을 대체하여 인터페이스1. 정적 메서드 참조

    Syntax

    : 클래스::정적 메서드

    참고:

      참조된 메서드 뒤에 괄호를 추가하지 마세요.
    • 참조된 메소드, 매개변수(숫자, 유형) 및 반환 값은 인터페이스
    • 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에 정의된 것과 일치해야 합니다. 비정적 메소드에 대한 참조

    Syntax

    : Object::non Static method

    Notes

    :

      참조된 메서드 뒤에 괄호를 추가하지 마세요.
    • 引用的这个方法, 参数(数量、类型) 和 返回值, 必须要跟接口中定义的⼀致。

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

    위 내용은 Java의 Lambda 표현식에 사용되는 메소드는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제