Java Java베이스 Java 8의 설탕 문법인 람다 표현식 소개

Java 8의 설탕 문법인 람다 표현식 소개

Feb 18, 2021 pm 06:09 PM
java8 lambda

Java 8의 설탕 문법인 람다 표현식 소개

추천 무료 학습: java 기본 튜토리얼

1. Lambda 표현식 소개

Lambda 표현식은 Java8의 새로운 기능이며 Java8에서 가장 배울 만한 새로운 기능 중 하나입니다. (또 다른 새로운 기능은 스트리밍 프로그래밍입니다.)

  • Lambda 표현식은 기본적으로 익명 메서드입니다. 이 익명 메서드를 사용하여 인터페이스에서 메서드를 구현할 수 있습니다. 匿名方法。可以使用这个匿名方法,实现接口中的方法

  • 功能:通常使用Lambda表达式,是为了简化接口实现的。关于接口实现可以有多种方式实现,例如:①设计接口的实现类、②使用匿名内部类。但是③使用lambda表达式,比这两种方式都简单。

  • 要求:lambda表达式,只能实现函数式接口:即一个接口中,要求实现类必须实现的抽象方法,有且只有一个。

@FunctionalInterface注解 ,用在接口之前,用来判断接口是否是一个函数式接口。如果不是函数式接口会报错。功能类似于@Override。

二、Lambda表达式语法

lambda表达式本质上是一个匿名方法,因此再写lambda表达式时,不需要关心方法名是什么,也不需要关心返回值类型。只需要关心两部分:参数列表方法体

  • ()参数部分:方法的参数列表,要求和实现的接口中的方法参数部分一致,包括参数的数量和类型。
  • {}方法体部分:方法的实现部分,如果接口中定义的方法有返回值,则在实现时,注意返回值的返回。
  • -> :分隔参数部分和方法体部分。
Lambda表达式基础语法:(参数) ->{
	方法体}
로그인 후 복사

下面定义6种参数和返回值各不相同的函数式接口,分别使用lambda表达式对接口中的方法进行实现:

Java 8의 설탕 문법인 람다 표현식 소개

下面是针对上面6种函数式接口的lambda表达式实现。

/**
 * @Description:
 * @author Guoqianliang
 * @date 19:50 - 2021/2/15
 */public class BasicSyntax {
    public static void main(String[] args) {
        // 1.实现无参数,无返回值的函数式接口
        NoneReturnNoneParameter lambda1 = () -> {
            System.out.println("这是无参,无返回值的方法");
        };
        lambda1.test();

        // 2.实现一个参数,无返回值的函数式接口
        NoneReturnSingleParameter lambda2 = (int a) -> {
            System.out.println("这是一个参数,无返回值的方法,参数a:" + a);
        };
        lambda2.test(10);

        // 3.实现多个参数,无返回值的函数式接口
        NoneReturnMutipleParameter lambda3 = (int a, int b) -> {
            System.out.println("这是多个参数,无返回值的方法,参数a=" + a + ",b=" + b);
        };
        lambda3.test(10, 20);

        // 4.实现无参数,有返回值有返回值的函数式接口
        SingleReturnNoneParameter lambda4 = () -> {
            System.out.println("这是无参数,有返回值的方法,返回值是:");
            return 10;
        };
        System.out.println(lambda4.test());

        // 5.实现一个参数,有返回值的函数式接口
        SingleReturnSingleParameter lambda5 = (int a) -> {
            System.out.println("这是一个参数,有返回值的方法,返回值是:");
            return a;
        };
        System.out.println(lambda5.test(10));

        // 6.实现多个参数,有返回值的函数式接口
        SingleReturnMutipleParameter lambda6 = (int a, int b) -> {
            System.out.println("这是多个参数,有返回值的方法,返回值是:");
            return a + b;
        };
        System.out.println(lambda6.test(1, 2));
    }}
로그인 후 복사

语法精简进阶:

  • 参数列表的参数类型可以省略。
  • 如果参数列表中的参数有且只有一个,可以省略小括号。
  • 如果方法体中只有一条语句,可以省略大括号。(注:如果这条语句是返回语句,省略了大括号后也要把return关键字省略)

三、函数引用

lambda表达式是为了简化接口。在lambda表达式中,不应该出现比较复杂的逻辑。如果需要处理的逻辑比较复杂,一般情况会单独写一个方法。在lambda表达式中直接引用这个方法即可。即引用一个已经存在的方法,使其代替lambda表达式完成接口的实现。

1.静态方法引用

语法:类::静态方法

  • 在引用的方法后面,不要添加小括号。
  • 引用的这个方法,参数(数量、类型)和返回值,必须要跟接口中定义的一致。
/**
 * @Description: 方法引用
 * @author Guoqianliang
 * @date 0:26 - 2021/2/16
 */public class Lambda1 {

    private static interface Calculate {
        int calculate(int a, int b);
    }

    private static int calculate(int x, int y) {
        if (x > y) {
            return x - y;
        } else if (x <p><strong>2.非静态方法引用</strong></p><blockquote>
<p>语法:<code>对象::非静态方法</code></p>
<ul>
<li>在引用的方法后面,不要添加小括号。</li>
<li>引用的这个方法,参数(数量、类型)和返回值,必须要跟接口中定义的一致。</li>
</ul>
</blockquote><pre class="brush:php;toolbar:false">/**
 * @Description: 方法引用
 * @author Guoqianliang
 * @date 0:26 - 2021/2/16
 */public class Lambda1 {

    private static interface Calculate {
        int calculate(int a, int b);
    }

    // 非静态方法
    private int calculate2(int a, int b) {
        if (a != b) {
            return a - b;
        }
        return a + b;
    }

    public static void main(String[] args) {
        // 非静态方法引用
        Calculate calculate2 = new Lambda1()::calculate2;
        System.out.println(calculate.calculate(10, 20));
    }}
로그인 후 복사

3.构造方法引用

语法:类名::new

  • 可以通过接口中的方法的参数,区分引用不同的构造方法。
  • 如果某一个函数式接口中定义的方法,仅仅是为了得到一个类的对象。此时就可以使用构造方法的引用,简化这个方法的实现。
/**
 * @Description: 构造方法引用
 * @author Guoqianliang
 * @date 11:20 - 2021/2/16
 */public class Lambda2 {

    @FunctionalInterface
    private interface GetPersonWithNoneParameter {
        Person get();
    }

    @FunctionalInterface
    private interface GetPersonWithSingleParameter {
        Person get(String name);
    }

    @FunctionalInterface
    private interface GetPersonWithMutipleParameter {
        Person get(String name, int age);
    }

    private static class Person {
        String name;
        int age;

        public Person() {
            System.out.println("Person类的无参构造方法执行了");
        }

        public Person(String name) {
            this.name = name;
            System.out.println("Person类的有参构造方法执行了");
        }

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
            System.out.println("Person类的两个参数的构造方法执行了");
        }
    }

    public static void main(String[] args) {
        // 1.使用lambda表达式,实现GetPersonWithNoneParameter接口
        GetPersonWithNoneParameter getPerson = Person::new;
        // 2.使用lambda表达式,实现GetPersonWithSingleParameter接口
        GetPersonWithSingleParameter getPerson2 = Person::new;
        // 3.使用lambda表达式,实现GetPersonWithMutipleParameter接口
        GetPersonWithMutipleParameter getPerson3 = Person::new;

        System.out.println(getPerson.get());
        System.out.println(getPerson2.get("树先生"));
        System.out.println(getPerson3.get("你好", 23));
    }}
로그인 후 복사

4.对象方法的特殊引用

使用lambda表达式实现某些接口时,如果lambda表达式中包含了某一个对象,此时方法体中,直接使用这个对象调用它的某一个方法就可以完成整体的逻辑。

/**
 * @Description: 对象方法的特殊应用
 * @author Guoqianliang
 * @date 11:54 - 2021/2/16
 */public class Lambda3 {

    @FunctionalInterface
    private interface MyInterface {
        // String get(Person person);
        void set(Person person, String name);
    }

    private static class Person {
        private String name;

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setName("小明");//        逻辑实现只是为了获取到对象的名字//        MyInterface lambda2 = Person::getName;//        System.out.println(lambda2.get(p1));
        
        // 逻辑实现只是为了给对象的某些属性进行赋值
        MyInterface lambda1 = (x, n) -> x.setName(n);
        MyInterface lambda2 = Person::setName;
        lambda2.set(p1, "李华");
        System.out.println(p1.getName());
    }}
로그인 후 복사

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

如果用到局部变量

함수: 람다 표현식은 일반적으로 인터페이스 구현을 단순화하는 데 사용됩니다. 인터페이스를 구현하는 방법에는 다음과 같은 여러 가지가 있습니다. ① 인터페이스의 구현 클래스를 디자인합니다. ② 익명 내부 클래스를 사용합니다. 하지만 ③ 람다 표현식을 사용하는 것이 이 두 가지 방법보다 더 간단합니다.

요구 사항: 람다 식, 기능적 인터페이스만 구현할 수 있음: 즉, 인터페이스에는 구현 클래스가 구현해야 하는 추상 메서드가 하나만 있습니다. @FunctionalInterface 주석은 인터페이스가 기능적 인터페이스인지 확인하기 위해 인터페이스 앞에 사용됩니다. 기능적 인터페이스가 아닌 경우 오류가 보고됩니다. 기능은 @Override와 유사합니다.

2. 람다 식 구문 🎜🎜🎜🎜람다 식은 기본적으로 익명 메서드이므로 람다 식을 작성할 때 메서드 이름이나 반환 값 유형에 신경 쓸 필요가 없습니다. 매개변수 목록메서드 본문 두 부분만 신경 쓰면 됩니다. 🎜🎜🎜🎜() 매개변수 부분: 메서드의 매개변수 목록은 매개변수의 수와 유형을 포함하여 구현된 인터페이스의 메서드 매개변수 부분과 일치해야 합니다. 🎜{}메서드 본문 부분: 메서드의 구현 부분입니다. 인터페이스에 정의된 메서드에 반환 값이 있는 경우 구현 시 반환 값에 주의하세요. 🎜-> : 매개변수 부분과 메소드 본문 부분을 분리합니다.
/**
 * @Description:
 * @author Guoqianliang
 * @date 13:05 - 2021/2/16
 */public class Lambda4 {
    public static void main(String[] args) {
        // 1.定义一个局部变量
        int x = 10;
        // 2.使用lambda表达式实现接口
        LambdaTest lambda = () -> {
            System.out.println("x=" + x);
        };
        // 3. 无法修改常量x
        // x=20;
    }}@FunctionalInterfaceinterface LambdaTest {
    void test();}
로그인 후 복사
🎜🎜다음은 다양한 매개변수와 반환 값을 사용하여 6가지 유형의 기능적 인터페이스를 정의하고 람다 식을 사용하여 인터페이스에 메서드를 구현합니다. 🎜🎜🎜 여기에 그림 설명 삽입🎜🎜🎜다음은 위의 6A에 대한 것입니다. 기능적 인터페이스의 람다 식 구현입니다. 🎜🎜rrreee🎜고급 구문 단순화: 🎜🎜🎜매개변수 목록의 매개변수 유형을 생략할 수 있습니다. 🎜매개변수 목록에 매개변수가 하나만 있는 경우 괄호를 생략할 수 있습니다. 🎜메서드 본문에 구문이 하나만 있는 경우 중괄호를 생략할 수 있습니다. (참고: 이 명령문이 return 문인 경우 중괄호를 생략한 후 return 키워드도 생략해야 합니다.)🎜🎜3. 함수 참조🎜🎜🎜🎜lambda 표현식은 인터페이스를 단순화하기 위한 것입니다. 람다 식에서는 더 복잡한 논리가 나타나서는 안 됩니다. 처리해야 하는 로직이 상대적으로 복잡한 경우 별도의 메소드를 작성하는 것이 일반적입니다. 람다 식에서 이 메서드를 직접 참조하면 됩니다. 즉, 는 람다 식을 대체하여 인터페이스 구현을 완료할 수 있도록 기존 메서드를 참조합니다. 🎜🎜🎜🎜1. 정적 메서드 참조🎜🎜🎜🎜 구문: Class::static 메서드🎜🎜🎜참조된 메서드 뒤에 괄호를 추가하지 마세요. 🎜참조된 메소드의 매개변수(숫자, 유형) 및 반환 값은 인터페이스에 정의된 값과 일치해야 합니다. 🎜rrreee🎜🎜2. 비정적 메서드 참조🎜🎜🎜🎜 구문: Object::non-static 메서드🎜🎜🎜참조된 메서드 뒤에는 추가하지 마세요. 괄호 🎜참조된 메소드의 매개변수(숫자, 유형) 및 반환 값은 인터페이스에 정의된 값과 일치해야 합니다. 🎜rrreee🎜🎜3. 생성자 메소드 참조🎜🎜🎜🎜 구문: 클래스 이름::new🎜🎜🎜에서 메소드의 매개변수를 통해 서로 다른 참조를 구별할 수 있습니다. 인터페이스 구축 방법. 🎜함수형 인터페이스에 정의된 메소드가 단지 클래스의 객체를 가져오기 위한 것이라면. 이 시점에서 생성자 메서드에 대한 참조를 사용하여 이 메서드의 구현을 단순화할 수 있습니다. 🎜rrreee🎜🎜4. 객체 메소드에 대한 특수 참조🎜🎜🎜🎜람다 표현식을 사용하여 특정 인터페이스를 구현할 때 람다 표현식에 객체가 포함되어 있으면 메소드 본문에서 이 객체를 사용하면 됩니다. 전체 논리를 완료하기 위해 해당 메서드 중 하나를 호출합니다. 🎜🎜rrreee🎜🎜4. 람다 표현식 사용 시 주의할 점🎜🎜🎜🎜로컬 변수를 사용하면 기본적으로 상수로 선언되며 값을 변경할 수 없습니다. 🎜🎜rrreee🎜🎜🎜관련 학습 권장사항: 🎜🎜🎜java basics🎜🎜🎜🎜

위 내용은 Java 8의 설탕 문법인 람다 표현식 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

람다 표현식은 C++에서 예외를 어떻게 처리하나요? 람다 표현식은 C++에서 예외를 어떻게 처리하나요? Apr 17, 2024 pm 12:42 PM

C++에는 Lambda 표현식을 사용하여 예외를 처리하는 두 가지 방법이 있습니다. 즉, try-catch 블록을 사용하여 예외를 포착하고, catch 블록에서 예외를 처리하거나 다시 발생시킵니다. std::function 유형의 래퍼 함수를 ​​사용하면 try_emplace 메서드가 Lambda 표현식에서 예외를 포착할 수 있습니다.

Java 8에서 1년 전 또는 1년 후의 날짜를 어떻게 계산합니까? Java 8에서 1년 전 또는 1년 후의 날짜를 어떻게 계산합니까? Apr 26, 2023 am 09:22 AM

Java8은 1년 전 날짜를 계산하기 위해 minus() 메소드를 사용하여 1년 전 또는 1년 후 날짜를 계산합니다. packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[ ]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

C++ 람다 표현식에서 클로저의 의미는 무엇입니까? C++ 람다 표현식에서 클로저의 의미는 무엇입니까? Apr 17, 2024 pm 06:15 PM

C++에서 클로저는 외부 변수에 액세스할 수 있는 람다 식입니다. 클로저를 생성하려면 람다 표현식에서 외부 변수를 캡처하세요. 클로저는 재사용성, 정보 숨기기, 지연 평가와 같은 이점을 제공합니다. 이는 클로저가 외부 변수가 파괴되더라도 여전히 접근할 수 있는 이벤트 핸들러와 같은 실제 상황에서 유용합니다.

다중 스레드 프로그래밍에 C++ 람다 식을 사용하면 어떤 이점이 있나요? 다중 스레드 프로그래밍에 C++ 람다 식을 사용하면 어떤 이점이 있나요? Apr 17, 2024 pm 05:24 PM

C++ 다중 스레드 프로그래밍에서 람다 식의 장점에는 단순성, 유연성, 매개 변수 전달 용이성 및 병렬성이 포함됩니다. 실제 사례: 람다 식을 사용하여 다중 스레드를 만들고 다른 스레드에서 스레드 ID를 인쇄하여 이 방법의 단순성과 사용 용이성을 보여줍니다.

C++ 람다 표현식에서 클로저를 구현하는 방법은 무엇입니까? C++ 람다 표현식에서 클로저를 구현하는 방법은 무엇입니까? Jun 01, 2024 pm 05:50 PM

C++ Lambda 표현식은 함수 범위 변수를 저장하고 함수에 액세스할 수 있도록 하는 클로저를 지원합니다. 구문은 [캡처 목록](매개변수)->return-type{function-body}입니다. 캡처 목록은 캡처할 변수를 정의합니다. [=]를 사용하여 모든 지역 변수를 값으로 캡처하고, [&]를 사용하여 모든 지역 변수를 참조로 캡처하거나, [변수1, 변수2,...]를 사용하여 특정 변수를 캡처할 수 있습니다. 람다 표현식은 캡처된 변수에만 액세스할 수 있지만 원래 값을 수정할 수는 없습니다.

C++ 람다 표현식은 외부 변수를 어떻게 캡처합니까? C++ 람다 표현식은 외부 변수를 어떻게 캡처합니까? Apr 17, 2024 pm 04:39 PM

C++에서 외부 변수의 람다 식을 캡처하는 방법에는 세 가지가 있습니다. 값으로 캡처: 변수의 복사본을 만듭니다. 참조로 캡처: 변수 참조를 가져옵니다. 값 및 참조로 동시에 캡처: 값 또는 참조로 여러 변수를 캡처할 수 있습니다.

C++ 함수 호출 람다 표현식: 매개변수 전달 및 반환 값에 대한 콜백 최적화 C++ 함수 호출 람다 표현식: 매개변수 전달 및 반환 값에 대한 콜백 최적화 May 03, 2024 pm 12:12 PM

C++에서는 Lambda 표현식을 함수 매개 변수로 사용하여 콜백 함수의 유연성을 얻을 수 있습니다. 구체적으로 설명하면 다음과 같습니다. 매개변수 전달: std::function을 통해 Lambda 표현식을 래핑하고 이를 함수 포인터 형식으로 함수에 전달합니다. 반환 값 처리: std::function을 사용하여 콜백 함수 포인터를 선언할 때 반환 값 유형을 지정합니다. 실제 사례: GUI 이벤트 처리에서 콜백을 최적화하고, 불필요한 객체나 함수 포인터 생성을 방지하고, 코드 단순성과 유지 관리성을 향상시킵니다.

Java 8을 사용하여 일주일 후 날짜를 계산하는 방법은 무엇입니까? Java 8을 사용하여 일주일 후 날짜를 계산하는 방법은 무엇입니까? Apr 21, 2023 pm 11:01 PM

Java8에서 일주일 후 날짜를 계산하는 방법 이 예에서는 일주일 후 날짜를 계산합니다. LocalDate 날짜에는 시간 정보가 포함되어 있지 않습니다. 해당 plus() 메서드는 일, 주 및 월을 추가하는 데 사용됩니다. ChronoUnit 클래스는 이러한 시간 단위를 선언합니다. LocalDate도 불변형이므로 반환 후 값을 할당하려면 변수를 사용해야 합니다. packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

See all articles