코린이의 소소한 공부노트

람다식의 정의와 작성 방법 본문

Java

람다식의 정의와 작성 방법

무지맘 2022. 12. 28. 21:12

[람다식의 정의]

1. 함수(메서드)를 간단한 식(expression)으로 표현한 것

int max(int a, int b){ return a>b ? a : b; }
// 짧게 표현한 식
(a, b) -> a>b ? a : b

2. 함수에 이름을 따로 붙이지 않으므로 익명 함수(anonymous function)라고도 한다.

  - 함수와 메서드는 근본적으로 동일하다.

  - 함수는 일반적으로 사용하는 용어로 클래스에 독립적이다.

  - 메서드는 객체지향에서 사용하는 용어로 클래스에 종속적이다.

 

[람다식 작성 방법]

1. 메서드의 이름과 반환 타입을 제거하고 ‘->’를 블록{} 앞에 추가한다.

int max(int a, int b){ return a>b ? a : b; }
// 바꾸게 되면
(int a, int b) -> { return a>b ? a : b; }

2. 반환 값이 있는 경우, 식이나 값만 적는다. return문은 생략 가능하고, 이때는 식의 끝에 세미 콜론;을 붙이지 않는다.

(int a, int b) -> { return a>b ? a : b; }
// retrun문과 ; 생략 가능
(int a, int b) -> a>b ? a : b

3. 매개변수의 타입이 추론 가능하면 생략할 수 있다. 대부분은 생략이 가능하다.

(int a, int b) -> a>b ? a : b
// 매개변수 타입을 생략하면
(a, b) -> a>b ? a : b

4. 매개변수가 1개인 경우, 타입을 생략할 때 괄호()도 같이 생략 가능하다.

(a) -> a*a // 이 람다식은 타입이 생략됐기 때문에
a -> a*a // 이렇게 바꿔도 된다.

(int a) -> a*a // 이 람다식은 타입이 있기 때문에
int a -> a*a // 이렇게 바꿀 수 없다.

5. 블록 안의 문장이 하나뿐일 때 괄호{}는 생략 가능하고, 끝에 세미 콜론을 붙이지 않는다.

(int i) -> { System.out.println(i); }
// {}와 ; 생략
(int i) -> System.out.println(i)
 
// 단, 하나뿐인 문장이 return문이면 괄호 생략이 불가하다.
(int a, int b) -> { return a>b ? a : b; } // OK
(int a, int b) -> return a>b ? a : b // 에러. {}와 ;을 생략할거면 return도 같이 생략해야 한다.

7. 람다식 작성 예시

int max(int a, int b) { return a > b ? a : b; }
// 가장 간단한 람다식으로 바꾸면
(a, b) -> a>b ? a : b

int printVar(String name, int i) { System.out.println(name+"="+i); }
// 가장 간단한 람다식으로 바꾸면
(name, i) -> System.out.println(name+"="+i)

int square(int x) { return x * x; }
// 가장 간단한 람다식으로 바꾸면
x -> x*x

int roll() { return (int)(Math.random()*6); }
// 가장 간단한 람다식으로 바꾸면
() -> (int)(Math.random()*6) // 매개변수가 없을 때 () 생략 불가

 

[람다식 다루기]

1. 람다식은 편의상 익명 함수로 불리지만, 사실은 익명 객체다.

(a, b) -> a>b ? a : b
// 위 람다식은 아래와 같은 익명 객체이다.
new Object(){
    int max(int a, int b){ return a>b ? a : b; }
}

2. 람다식을 다루기 위한 참조변수가 필요하다. 참조변수의 타입은 어떤 것일까?

// 위에서 람다식을 Object 객체로 바꿔썼으니, 람다식의 참조변수 타입은 Object인가봐
Object obj = new Object(){
    int max(int a, int b){ return a>b ? a : b; }
};
// 이제 이용해보자
int value = obj.max(3,5); // 에러. obj객체에는 max()가 있지만
			// Object 클래스에는 max()가 없어서 사용 불가

3. 람다식을 다루려면 함수형 인터페이스가 필요하다.

// 위에서 obj를 선언할 때 쓴 익명 객체를 람다식으로 바꾸면
// 다음과 같은 컴파일 에러가 난다.
Object obj = (a, b) -> a>b ? a : b;
// error: The target type of this expression must be a functional interface