람다식은 익명 함수(anonymous function)를 생성하기 위한 식입니다. 이는 객체 지향 언어라기보다는, 함수 지향 언어에 가까운 성격을 갖고 있습니다. 일단 기존의 코드 작성 레이아웃과 약간의 차이가 있는 형태이지만, 결과적으로는 코드 자체가 간결해지고, 컬렉션을 다룰 때 원하는 결과를 쉽게 필터링/매핑할 수 있다는 장점이 있습니다.
람다식 자체는 기본적으로 '파라미터를 가진 코드 블럭' 형태이지만 런타임 시에는 "익명 구현 객체"를 생성하게 됩니다. 익명 구현 객체를 생성한다는 부분에서 눈치채셨겠지만, 인터페이스를 구현한다는 의미입니다. 이와 관련해서는, 익명 객체 아티클에서 인터페이스의 또는 부모 객체에 대한 익명 구현 객체 생성을 배웠습니다.
익명 객체와 관련해서는 생각보다 복잡한 내용을 배웠었으니, 기억이 나지 않으신다면 이전 아티클을 가볍게 훑어보고 오시는 것을 추천합니다.
[부모-자식 관계 익명 객체]
[인터페이스 익명 구현 객체]
일단 Runnable이라는 인터페이스에 대해서, 익명 구현 객체를 선언하면 다음과 같습니다.
Runnable runnable = new Runnable() {
public void run() { // ... }
};
다시 한번 설명하자면, 이 선언 코드에서 new Runnable()은 인터페이스 생성자를 호출하는 개념으로 봐주면 될 것이고, 하단의 메서드는 오버라이드 하는 구간입니다. 이렇게 재정의가 된 (익명의) 구현 객체를 하나 생성하는 것입니다. 자, 이제 익명 구현 객체를 람다식으로 표현해 보겠습니다.
Runnable runnable = () -> { // 실행문 };
위에서 작성한 예시와 같이, 람다식은 기본적으로 (파라미터) -> { 실행 코드 }의 형태를 띠게 됩니다. 실제로 런타임 시점에는 이 람다식이 인터페이스의 익명 구현 객체로 생성됩니다. 당연히 위의 예제 코드의 경우에는 인터페이스 Runnable의 익명 구현 객체를 생성하게 되는 것이죠.
기본적인 람다식의 문법을 살펴보겠습니다. 함수 스타일의 람다식 기본 작성 방식은 위에서 살펴본 예시와 같이, 다음 형태를 갖게 됩니다.
(타입 파라미터, ...) -> { 실행문; ... }
당연한 이야기이지만, 왼쪽의 파라미터 정의가 진행되면 이는 { } 블록을 실행하기 위해서 필요한 값을 제공하는 역할을 하게 됩니다. 파라미터 이름은 개발자가 자유롭게 지정합니다. 간혹 ' -> ' 기호의 의미를 궁금해하는데, 여기서는 "해당 파라미터를 이용해서 { } 블록의 실행문을 실행한다"라고 이해하시면 됩니다.
그럼 가장 기본적인 형태의 예시를 들어보겠습니다.
(int a) -> { System.out.println(a); }
여기서 파라미터에서 타입인 int를 선언했습니다. 그런데, 파라미터 데이터 타입은 런타임시에 대입되는 값을 이용해 자동으로 인식이 가능해서 생략하는 경우가 일반적입니다. 그래서 다음과 같이 작성이 가능합니다.
(a) -> { System.out.println(a); }
위에서 파라미터 타입을 생략했는데, 여기서도 생략이 더 가능합니다. 바로 파라미터가 한 개, 실행문이 한 개일 경우입니다. 이런 경우에는 괄호와 { } 블록이 생략 가능합니다.
a -> System.out.println(a)
단, 파라미터가 아예 없는 경우라면 공백으로 두는 것은 불가능하므로 ( ) -> { ... } 형태로 작성해야 합니다.
어떤 실행코드가 return이 필요한 경우라면, 당연히 다음과 같이 return 문을 표시합니다. 예를 들어 파라미터 x, y의 값을 더해서 리턴하는 경우라면 다음과 같이 표시합니다.
(x, y) -> { return x + y; };
하지만 { } 블록에 return문만 존재한다면, 람다식에서는 return 문을 사용하지 않고 다음과 같이 작성하는 것이 일반적입니다.
(x, y) -> x + y
'Programming > JAVA' 카테고리의 다른 글
람다식(2) - 람다식의 타겟 타입, 함수적 인터페이스 2 (0) | 2023.05.15 |
---|---|
람다식(2) - 람다식의 타겟 타입, 함수적 인터페이스 1 (1) | 2023.05.12 |
제네릭(6) - 제네릭 타입의 상속과 구현 (0) | 2023.05.09 |
제네릭(5) - 와일드카드 타입 (0) | 2023.05.06 |
제네릭(4) - 제한된 타입 파라미터 선언 (0) | 2023.05.03 |