[Java] 람다식과 익명 클래스
람다식은 어디서 왔을까?
함수형 언어가 다시 주목받으며 자바도 함수형의 이점을 살리기 위한 여러 기능이 업데이트되었다. 특히 자바 8에서 소개된 람다식이 대표적인 예이다.
함수형에서는 여러 클래스나 값을 변경하고 상호작용을 구현하여 표현하지 않는다. 보통 코드를 보면 무엇을 하는지 한눈에 보이고 데이터나 이벤트 스트림이 처리되는 과정을 가독성 좋게 볼 수 있다.
이런 데이터나 스트림을 다루는 데에 있어서 작은 동작이나 일회성 작업에 이름을 붙일 필요가 없는 경우가 많다. 그럴 때 쓸 수 있는 것이 람다식 혹은 익명 함수이다. 클래스명 같은 이름이 없기 때문에 그저 하나의 람다식으로 쉽게 전달될 수 있기도 하다.
람다식과 익명 클래스
람다식, 익명 클래스 모두 이름이 없는 함수나 객체를 표현하기 위해 쓰인다.
하지만 함수형 인터페이스에 대한 구현을 제공하기 위해 만들어진 람다식 문법을 사용하면 익명 클래스보다 더 간결하게 표현될 수 있다. 그 차이점을 보자.
익명 클래스로 데이터를 어떻게 매핑할지 정의한 예시
람다식으로 데이터를 어떻게 매핑할지 정의한 예시
Runnable을 오버라이딩하는 예시도 보자.
// 익명 클래스
Runnable runnable = new Runnable() {
@Override // <--
public void run() {
System.out.println("익명 클래스닷!");
}
};
// 람다식
Runnable runnable = () -> System.out.println("람다식이닷!");
보면 람다식은 new, 클래스명 등을 생략하고 더 간결하게 표현하여 원하는 로직만 보이게 하고 싶은 경우 가독성을 높일 수 있다.
말고도 람다식은 함수형을 지원하려는 만큼 매개변수나 변수로 전달되어 재사용될 수 있다.
람다식
람다식은 기본적으로 다음과 같이 만들 수 있다.
(매개변수 목록) -> { 실행문; }
매개변수가 하나인 경우 괄호를 생략할 수 있다.
단일_매개변수 -> { 실행문; }
이러한 람다식은 주로 일련의 데이터(컬렉션, 스트림, 등)의 요소를 처리할 때 자주 쓰이기 때문에 익숙해지자!
다음은 1부터 10까지의 숫자 배열 중 짝수만 필터링하여 모든 합을 구해보는 예시이다.
@Test
void testLambda() {
// Given
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// When
int sum = numbers.stream().mapToInt(Integer::intValue).filter(n -> n % 2 == 0).sum();
// Then
assertEquals(30, sum);
}
filter 할 조건으로 람다식을 사용했다. 각각의 요소를 int -> filter(조건: 짝수만) => 합!
요즘은 이러한 스트림은 인텔리제이 같은 도구의 디버깅 기능을 쓰면 디버깅하기 편하다.
디버깅 모드에서 볼 수 있는 Trace Current Stream Chain 기능은 이런 흐름을 시각화를 해준다.
하지만 이렇다고 해서 남용은 안 된닷! 람다식이 여러 조건을 처리하거나 로직이 복잡하면 이걸 보는 입장에서 골치가 아파진다.
댓글
이 글 공유하기
다른 글
-
서로 닮아 보이는 Decorator, Composite Pattern - 1편
서로 닮아 보이는 Decorator, Composite Pattern - 1편
2025.01.15 -
IntelliJ 자주 쓰는 단축키 모음
IntelliJ 자주 쓰는 단축키 모음
2024.10.23 -
[Java] Annotation (feat. Reflection)
[Java] Annotation (feat. Reflection)
2024.02.19