우주먼지
Published 2023. 2. 19. 10:39
Lambda Languages/Java

💡 Lambda Expression

 

람다식은 메서드를 하나의 '식(expression)'으로 표현한 것이다

람다식은 함수를 간략하게하면서도 명확한 식으로 표한할 수 있게 해준다

메서드를 람다식으로 표한하면 메서드의 `이름 & 반환값`이 없어지므로 람다식을 `익명 함수`라고도 한다

int[] arr = new int[5];
Arrays.setAll(arr, i -> (Math.random() * 5) + 1);

람다식 작성하기

 

  • 람다식은 익명함수답게 메서드에서 이름과 반환타입을 제거하고 매개변수 선언부와 몸통{} 사이에 ->를 추가한다
  • 람다식에 선언된 매개변수의 타입은 추론이 가능한 경우는 `생략`이 가능하다
  • 반환값이 있는 메서드의 경우 (반환타입이 void가 아닌 경우) return 문 대신 식으로 대신 할 수 있다
  • 람다는 `문장`이 아닌 `식` 이므로 끝에 `;`를 붙이지 않는다
  • 매개변수가 하나인 경우에는 `괄호()`를 생략할 수 있지만, 매개변수의 `타입`이 있다면 `괄호()`를 생략할 수 없다 마찬가지로 `괄호{}` 안의 문장이 한 문장일 경우 생략가능하며 문장의 끝에 `;`를 붙이지 않는다
반환타입 메서드이름 (매개변수) {
	실행 문장;
}

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

// 반환 타입과 메서드 이름이 사라졌다

(매개변수) -> {
	실행 문장
}

예를 들어 두 값 중 큰 값을 반환하는 max 메서드를 보면 아래 코드처럼 된다

int max(int a, int b) {
    return a > b ? a : b;
}

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

// 매개변수의 타입 추론으로 인한 타입 생략

(a, b) -> {
    return a > b ? a : b;
}

아래와 같이 선언된 매개변수가 하나뿐인 경우에는 괄호()를 생략할 수 있다

단, 매개변수의 타입이 있으면 괄호()를 생략할 수 없다

마찬가지로 `{}`도 한 문장이면 `{}`를 생략 가능하지만, 문장의 끝에 `;`를 붙이면 안된다

(a) -> a * a      =>  a -> a * a // OK

(int a) -> a * a  =>  int a -> a * a // 에러, 타입이 있으면 괄호를 생략할 수 없다
    
(String name, int i) -> System.out.println(name + "=" + i); // 에러, ;을 붙이면 안됨

함수형 인터페이스

 

자바에서 모든 메서드는 클래스 내에 포함되어야 하고, 메서드와 람다를 동등한것처럼 설명했지만

사실 람다는 `익명 클래스의 객체`와 동일하다

이 때, 람다식으로 정의된 익명 객체의 메서드를 어떻게 호출할 것인가?

예를 들어 한 람다식을 a 라는 참조 변수에 저장해보자

타입 a = (int a, int b) -> a > b ? a : b // 참조변수의 타입은?

참조변수니까 클래스 or 인터페이스가 가능하며 람다식과 동등한 메서드가 정의되어 있는 것이어야 한다

그래야만 참조변수로 익명 객체(람다식)의 메서드를 호출할 수 있다

아래 코드 예시를 보자

// 인터페이스
interface TestFunction {
    public abstract int max(int a, int b);
}

// 익명 클래스를 구현한 구현 객체
TestFunction a = 
    new TestFunction() {
    public int max(int a, int b) {
        return a > b ? a : b;
    }
}
int big = a.max(5, 3);

// 위의 익명 객체를 람다식으로 대체하여 메서드 호출
TestFunction a = (int a, int b) -> a > b ? a : b;
int big = a.max(5, 3);

이렇게 TestFunction 인터페이스를 구현한 익명 객체를 람다식으로 대체가 가능한 이유는,

람다식도 실제로는 익명 객체이고, 인터페이스를 구현한 익명 객체 메서드의

매개변수, 타입, 개수, 반환값이 일치하기 때문이다

 

그래서 인터페이스를 통해 람다식을 다루기로 결정되었으며

람다식을 다루기 위한 인터페이스를 `함수형 인터페이스`라고 부른다 (@FunctionalInterface 어노테이션 사용)

단, 함수형 인터페이스는 오직 `하나의 추상 메서드`만 정의되어 있어야 한다는 제약이 있다

그래야 람다식과 인터페이스의 메서드가 1:1 매칭으로 연결될 수 있기 때문이다

반면에 static 메서드와 default 메서드의 개수에는 제약이 없다

'Languages > Java' 카테고리의 다른 글

Thread  (0) 2023.03.01
J2EE  (0) 2023.02.20
ObjectMapper  (0) 2023.01.09
Method 공부  (0) 2022.09.28
Annotation & Lambda & Stream & I/O  (0) 2022.09.15
profile

우주먼지

@o귤o

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그