3 분 소요

람다식

  • 자바의 함수적 프로그래밍을 위해 람다식 지원
  • 익명 함수를 생성하기 위한 식 ⇒ 객체 지향 언어보다 함수 지향 언어에 가까움
  • 람다식 ⇒ 매개 변수를 가진 코드 블록 ⇒ 익명 구현 객체

      // Runnable 인터페이스의 익명 구현 객체
      Runnable runnable = new Runnable() {
      	public void run() { ... }
      }
        
      // 람다식 표현
      Runnable runnable = () -> { ... }
    

기본 문법

(타입 매개변수, ...) -> { 실행문; }
  • 매개 변수 타입은 런타임 시에 대입되는 값에 따라 자동으로 인식
  • 하나의 매개변수나 실행문만 있으면 괄호 생략 가능
  • 매개 변수가 없어도 빈 괄호를 반드시 사용
  • 결과값 return 가능

타겟 타입과 함수적 인터페이스

  • 인터페이스 변수 = 람다식;
    • 람다식은 인터페이스 변수에 대입 ⇒ 인터페이스의 익명 구현 객체 생성
    • 타겟 타입 : 람다식이 대입될 인터페이스

함수적 인터페이스

  • 모든 인터페이스를 람다식의 타겟 타입으로 사용할 수 없음
    • 람다식은 하나의 메소드 정의
    • 두개 이상의 추상 메소드가 선언된 인터페이스는 람다식을 이용해서 구현 객체 생성 불가
  • @FunctionalInterface : 함수적 인터페이스 작성 시 두 개 이상의 추상 메소드가 선언되지 않도록 컴파일러가 체크
    • 선택사항 ⇒ 없어도 하나의 추상 메소드만 있다면 모두 함수적 인터페이스

람다식의 매개 변수와 리턴값

  • 메소드에 따라 달라짐
    • 메소드가 매개 변수와 리턴값을 갖지 않기 때문에 람다식에도 없음
    • 메소드가 매개 변수를 갖거나 리턴값을 가지면 람다식에도 있음

클래스 멤버와 로컬 변수 사용

클래스 멤버 사용

  • 람다식 실행 블록에는 클래스 멤버인 필드, 메소드 제약 사항 없이 사용 가능
  • this 키워드 사용 시 주의 필요
    • 익명 객체 내부 this ⇒ 익명 객체의 참조
    • 람다식 this ⇒ 람다식을 실행할 객체 참조
    • 람다식의 바깥 객체를 얻기 위해서는 클래스명.this 사용

로컬 변수 사용

  • 람다식은 메소드 내부에서 주로 작성 ⇒ 로컬 익명 구현 객체 생성
  • 매개 변수, 로컬 변수를 람다식에서 읽는 것은 허용
  • 람다식 내부 또는 외부에서 변경 불가

표준 API 함수적 인터페이스

  • 자바에서 제공되는 표준 API에서 한 개의 추상 메소드를 가지는 인터페이스들은 모두 람다식 이용해서 익명 구현 객체로 표현 가능

Consumer 함수적 인터페이스

  • 리턴값 없는 accept() 메소드 ⇒ 매개값을 소비하는 역할

supplier 함수적 인터페이스

  • 매개값 없고 리턴값만 있는 메소드(get()) 가짐
  • 실행 후 호출한 곳으로 데이터를 리턴하는 역할

Function 함수적 인터페이스

  • 매개값과 리턴값이 있는 apply() 메소드 가짐
  • 매개값을 리턴값으로 매핑하는 역할

Operator 함수적 인터페이스

  • Function과 동일하게 매개 변수와 리턴값 있는 apply() 메소드
  • 매개값을 이용해서 연산을 수행한 후 동일한 타입으로 리턴값 제공하는 역할

Predicate 함수적 인터페이스

  • 매개 변수와 boolean 리턴값이 있는 test() 메소드
  • 매개값을 조사해서 true, false 리턴하는 역할

andThen()과 compose() 디폴트 메소드

  • 두 개의 함수적 인터페이스를 순차적으로 연결하고, 첫 번째 처리 결과를 두 번째 매개값으로 제공해서 최종 결과값을 얻을 때 사용
  • andThen()

      인터페이스AB = 인터페이스A.andThen(인터페이스B);
      최종결과 = 인터페이스AB.method();
    
    • 인터페이스A부터 처리하고 결과를 인터페이스B의 매개값으로 제공
  • compose()

      인터페이스AB = 인터페이스A.compose(인터페이스B);
      최종결과 = 인터페이스AB.method();
    
    • 인터페이스B부터 처리하고 결과를 인터페이스A의 매개값으로 제공
  • Consumer의 순차적 연결
    • Consumer 종류의 함수적 인터페이스는 처리 결과 리턴하지 않음 ⇒ andThen() 디폴트 메소드는 함수적 인터페이스의 호출 순서만 정함
  • Function의 순차적 연결
    • Function, Operator 종류의 함수적 인터페이스는 먼저 실행한 함수적 인터페이스의 결과를 다음 함수적 인터페이스의 매개값으로 넘겨주고 최종 처리 결과 리턴

and(), or(), negate() 디폴트 메소드와 isEqual() 정적 메소드

  • Predicate 종류의 함수적 인터페이스는 and(), or(), negate() 디폴트 메소드 가짐
  • 각각 논리 연산자 &&, ||, !과 대응

minBy(), maxBy() 정적 메소드

  • 매개값으로 제공되는 comparator를 이용해서 최대 T와 최소 T를 얻는 BinaryOperator 리턴
  • compare(a, b) ⇒ a, b를 비교해서 a가 크면 양수, 같으면 0, a가 작으면 음수 리턴

메소드 참조

  • 메소드를 참조해서 매개 변수의 정보 및 리턴 타입을 알아내 람다식에서 불필요한 매개 변수를 제거하는 것이 목적

정적 메소드와 인스턴스 메소드 참조

  • 정적 메소드 ⇒ 클래스 이름 뒤에 :: 기호 붙이고 정적 메소드 이름 기술
    • 클래스 :: 메소드
  • 인스턴스 메소드 ⇒ 객체를 먼저 생성한 다음 참조 변수 뒤에 :: 기호 붙이고 인스턴스 메소드 이름 기술
    • 참조변수 :: 메소드

매개 변수의 메소드 참조

  • 메소드는 람다식 외부 클래스 멤버 또는 람다식에서 제공되는 매개 변수의 멤버
    • 클래스 :: instanceMethod

생성자 참조

  • 생성자를 참조한다는 것 ⇒ 객체 생성
  • 단순히 객체를 생성하고 리턴하도록 구성된 람다식 ⇒ 생성자 참조로 대치 가능
    • 클래스 :: new