본 내용은 자바의 정석 3rd Edition을 참고하여 작성되었습니다. 개인적으로 학습한 내용을 복습하기 목적이기 때문에 내용상 오류가 있을 수 있습니다.
1. 람다식(Lambda expression
)이란?
람다식은 간다히 말해서 메서드를 하나의 식으로 표현한 것이다. 메서드를 람다식으로 표현하면 메서드의 이름과 반환값이 없어지므로 람다식을 익명함수(anonymous function) 라고도 한다. 이전에 Collection
의 Arrays
를 정리하면서 일부 코드에서 람다식을 봤었는데 그 코드를 메서드로 표현하면 아래와 같다.
위의 코드를 보면 메서드보다 람다식이 간결하고 이해하기 쉽다는 것을 알 수 있다. 게다가 모든 메서드는 클래스에 포함되어야 하므로 클래스도 새로 만들어야 하고, 객체도 생성해야만 비로소 메서드를 호출할 수 있다. 그러나 람다식은 이 모든 과정없이 오직 람다식 자체만으로도 이 메서드의 역할을 수행할 수 있다. 람다식은 메서드의 매개변수로 전달하는 것이 가능 하고, 메서드의 결과로 반환 될 수도 있다. 람다식으로 메서드를 변수처럼 다루는 것이 가능 해진 것이다.
2. 람다식 작성하기
람다식은 익명함수답게 메서드에서 이름과 반환타입을 제거하고 매개변수 선언부와 몸통{}
사이에 ->
를 추가 한다.
# 메서드를 람다식으로 변환 과정 및 주의 사항
# 람다식 변환 예제 1
# 람다식 변환 예제 2
# 람다식 변환 예제 3
# 람다식 변환 예제 4
# 람다식 변환 예제 5
3. 함수형 인터페이스(functional interface)
# 익명클래스와 함수형 인터페이스
자바에서는 모든 메서드는 클래스 내에 포함되어 있어야 하는데 람다식은 어떤 클래스에 포함되는 것일까? 람다식이 메서드와 동등한 것처럼 설명했지만, 사실 람다식은 익명클래스의 객체와 동등하다.
그렇다면 람다식으로 정의된 익명 객체의 메서드를 어떻게 호출할 수 있을까? 이미 알고 있듯이 참조변수가 있어야 객체의 메서드를 호출할 수 있으므로 익명객체의 주소를 f
라는 참조변수에 저장한다.
참조변수 f
의 타입은 어떤 것이야할까? 참조형이기때문에 클래스 또는 인터페이스가 가능하다. 그리고 람다식과 동등한 메서드가 정의되어 있는 것 이어야 한다.
이제 이 인터페이스를 구현한 익명 클래스의 객체는 아래의 코드와 같이 생성을 할 수 있다.
MyFunction
인터페이스에 정의된 메서드 max()
는 람다식 (int a, int b) -> a > b ? a : b
과 메서드 선언부가 일치하기 때문에 위 코드의 익명 객체를 람다식으로 대체할 수 있다.
MyFunction
인터페이스를 구현한 익명 객체를 람다식으로 대체가 가능한 이유는, 람다식도 실제로 익명객체이고, MyFunction
인터페이스를 구현한 익명 객체의 메서드 max()
와 람다식의 매개변수 타입과 갯수, 반환값이 일치하기 때문이다.
지금까지 살펴본 것처럼 인터페이스를 통해 람다식을 다룰수 있고, 이러한 인터페이스를 함수형 인터페이스(Functional interface) 라고 부른다. 함수형 인터페이스는 오직 하나의 추상메서드만 정의되어 있어야 한다는 제약이 있다. 그 이유는 람다식과 인터페이스의 메서드가 1:1로 연결되어야 하기 때문이다. 반면에 static
메서드와 default
메서드의 갯수에는 제약이 없다.
기존에는 아래의 코드 첫번째와 같이 인터페이스의 메서드 하나를 구현하는데도 복잡하게 해야 했다. 하지만 아래의 2번째 코드와 같이 람다식으로 처리하면 간단하게 처리를 할 수 있게 된다.
# 함수형 인터페이스 타입의 매개변수
함수형 인터페이스 MyFunction
이 아래의 첫번째 코드와 같이 정의가 되있고, 두번째 코드와 같이 매서드의 매개변수가 MyFunction
타입이면, 이 메서드를 호출할 때 람다식을 참조하는 참조변수를 매개변수로 지정해야 한다.
# 함수형 인터페이스 타입의 반환타입
메서드의 반환타입이 함수형 인터페이스라면, 이 함수형 인터페이스의 추상메서드와 동등한 람다식을 가리키는 참조변수를 반환하거나, 람다식을 직접 반환할 수 있다.
람다식을 참조변수로 다룰수 있다는 것은 메서드를 통해 람다식을 주고 받을 수 있다는 것, 즉 변수처럼 메서드를 주고 받을 수 있다는 것을 의미한다.
# 함수형 인터페이스 예제 1
# 람다식의 타입과 형변환
함수형 인터페이스로 람다식을 참조할 수 있는 것일 뿐, 람다식의 타입이 함수형 인터페이스의 타입과 일치하는 것은 아니다. 람다식은 익명 객체이고, 익명 객체는 타입이 없다. 정확히는 타입이 있지만 컴파일러가 임의의 이름을 정하기 때문에 알 수 없는 것이다. 그래서 대입 연산자의 양변의 타입을 일치시키기 위해 아래와 같이 형변환이 필요하다.
람다식은 Object
타입으로 형변환은 할 수없다. 그럼에도 Object
타입으로 형변환을 하려면 함수형 인터페이스로 형변환을 먼저 해야한다.
댓글을 사용할 수 없습니다.