ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [live-study] 15주차 :: 람다식
    JAVA/라이브 스터디 | whiteship 2021. 3. 6. 12:00

    참고도서 : Java의 정석(3rd Edition), 이것이 자바다

     

     

     


    0. 람다식

    람다식 (Lambda Expression)
    • 람다식은 간단히 말해서 메소드를 하나의 식(expression)으로 표현한 것이다.
    • 자바 8부터 람다식을 지원하였다.
    • 람다식은 익명 함수(anonymous function)를 생성하기 위한 식으로 객체 지향 언어보다는 함수 지향 언어에 가깝다.
    람다식 장점
    • 자바 코드가 매우 간결해졌다.
    • 컬렉션의 요소를 필터링하거나 매핑해서 원하는 결과를 쉽게 집계할 수 있다.

     

    1. 람다식 사용법

    람다식 형태
    • 람다식은 매개 변수를 가진 코드 블록이지만, 런타임 시에는 익명 구현 객체를 생성한다.

    • 예를 들어, Runnable 인터페이스의 익명 구현 객체를 생성하는 코드는 아래와 같다.
    • 람다식은 (매개변수) -> {실행코드} 형태로 작성되고, 런타임시에 인터페이스의 익명 구현 객체로 생성된다.

    람다식 기본 문법
    • 람다식은 (타입 매개변수) -> {실행코드} 형태로 작성된다. 

    • 예를 들어, int 타입의 매개변수 a의 값을 출력하려면 다음과 같이 작성할 수 있다.

    • 그리고, 매개 변수 타입은 런타임 시에 대입되는 값에 따라 자동으로 인식될 수 있으므로, 일반적으로 언급하지 않는다.

    • 또한, 지금의 예제와 같이 매개 변수가 하나만 있다면 괄호를 생략할 수도 있고, 실행문이 하나만 있다면 중괄호 { }도 생략할 수 있다.

     

    2. 함수형 인터페이스

    함수형 인터페이스
    • 모든 인터페이스를 람다식의 타겟 타입으로 사용할 수는 없다.
    • 람다식이 하나의 메소드를 정의하기 때문에, 두 개 이상의 추상 메소드가 선언된 인터페이스는 람다식을 이용해서 구현 객체를 사용할 수가 없다.
    • 즉, 하나의 추상메소드가 선언된 인터페이스만이 람다식의 타겟 타입이 될 수 있다. 
    • 이러한 인터페이스를 함수형 인터페이스(Functional Interface)라고 한다.
    • 인터페이스 선언 시 @FunctionalInterface 어노테이션을 붙이는데, 두 개 이상의 추상 메소드가 선언되면 컴파일 오류를 발생시킨다.

     

    3. Variable Capture

    Variable Capture
    • Java 람다식은 어떠한 특정 상솽에서 람다 함수 body 외부에 선언된 변수에 접근할 수 있다.
    • 종류로는 로컬 변수, 인스턴스 변수, 정적 변수 캡쳐가 있다.
    Local Variable 
    • Java 람다식은 함수 body 외부에 선언되어 있는 local 변수의 값에 접근할 수 있다.
    • 이 때 "effectively final"이어야 한다. effectively final이란 final이 붙어 있지 않은 변수의 값이 변경되지 않는 것을 말한다.

    Instantce Variable
    • Java 람다식은 instance 변수에도 접근이 가능하다.
    • 람다 본문에 있는 this.name에 대한 참조를 살펴조면, 이는 EventConsumerImpl 오브젝트의 name 인스턴스 변수를 캡쳐한다.
    • 캡쳐 후 인스턴스의 변수 값을 변경할 수도 있으며 값은 람다 내부에도 반영이 된다.

    Static Variable
    • Java 람다식은 또한 static 변수에도 접근을 할 수 있다. 하지만 사실 static 변수는 어디에서나 접근이 가능하기에 놀랄만한 일은 아니다.

     

    4. 메소드, 생성자 레퍼런스

    메소드 레퍼런스
    • 메소드 레퍼런스(Method References)는 말 그대로 메소드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내어, 람다식에 불필요한 매개 변수를 제거하는 것이 목적이다.
    • 예를 들어, 두 개의 값을 받아 더 큰 수를 리턴하는 Math 클래스의 max() 정적 메소드를 호출하는 람다식은 아래와 같다.

    • 여기서 람다식은 단순히 두 개의 값만을 Math.max() 메소드의 매개값으로 전달하는 역할만 하고 있다.
    • 그래서 아래와 같이 메소드 참조를 이용하여 간결하게 표현할 수 있다.

    • 람다식을 메소드 참조로 변환하는 방법을 다음과 같이 정리할 수 있다.

    • 즉, 하나의 메소드만 호출하는 람다식은 클래스이름::메소드이름 또는 참조변수::메소드이름으로 바꿀 수 있다.

     

    생성자 레퍼런스
    • 메소드 레퍼런스는 생성자 레퍼런스(Method References)도 포함한다.
    • 생성자를 레퍼런스한다는 것은 객체 생성을 의미한다. 
    • 단순히 객체를 생성하고 리턴하도록 구성된 람다식은 생성자 참조로 대치할 수 있다.
    • 아래 코드는 단순히 객체 생성 후 리턴만 하는 것을 볼 수 있다.

    • 이런 경우, 생성자 참조로 표현하려면 클래스 이름 뒤에 :: 기호를 붙이고 new 연산자를 기술하면 된다.

     

     

    참고자료

    댓글

Programming Diary