마스터링 Java 8 (Lambda expression & functional interface) - Day 2

발행: (2026년 2월 2일 오전 12:55 GMT+9)
6 min read
원문: Dev.to

Source: Dev.to

번역할 텍스트를 제공해 주시겠어요? 해당 내용을 한국어로 번역해 드리겠습니다.

람다 식이란? – “익명 함수”

람다 식익명 (이름 없는) 함수를 간결하게 표현하는 방법입니다. 코드를 “데이터처럼” 다룰 수 있게 해 주며, 보일러플레이트를 크게 줄여줍니다.

구조

(parameters) -> { body }
항목설명
(parameters)입력 인수.
• 매개변수가 하나일 경우 → 괄호 생략 가능, 예: s -> …
• 매개변수가 없을 경우 → 빈 괄호, 예: () -> …
-> (arrow token)매개변수 목록과 구현을 구분합니다. “~로 가다” 혹은 “실행한다” 라는 의미로 읽습니다.
{ body }실행할 코드.
• 단일 표현식 → {}return 키워드를 생략 (결과가 암묵적으로 반환됩니다).
• 여러 문장 → {}를 유지하고 값이 필요할 때 return을 사용합니다.

Example: Old Way vs. Lambda Way

Before Java 8 – Anonymous Inner Class

button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Button clicked!");
    }
});

Anonymous inner class example

With a Lambda Expression – Clean & Concise

button.addActionListener(e -> System.out.println("Button clicked!"));

Lambda expression example

람다식이 모든 불필요한 코드를 제거하고 순수하게 동작에만 집중하는 모습을 확인하세요.

“람다”를 위한 “홈” – 함수형 인터페이스

함수형 인터페이스정확히 하나의 추상 메서드만 선언하는 모든 인터페이스를 말합니다.
기본 메서드나 정적 메서드를 여러 개 포함할 수 있지만, 구현이 필요한 메서드는 오직 하나뿐입니다.

일반적으로 제공되는 내장 함수형 인터페이스:

  • Runnable
  • Callable
  • Comparator

Java 8에서는 java.util.function 패키지를 도입했으며, 여기에는 바로 사용할 수 있는 풍부한 함수형 인터페이스가 포함되어 있습니다.

빅 포 – 필수 java.util.function 인터페이스

이 네 가지는 가장 자주 사용하게 될 핵심 도구입니다.

1️⃣ Predicate테스터

  • 목적: 타입 T의 값을 받아 boolean을 반환합니다. 필터링이나 조건 검사에 이상적입니다.
  • 추상 메서드: boolean test(T t)

예시 – 숫자가 짝수인지 확인

Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4)); // true

Predicate 예시

2️⃣ Function변환기

  • 목적: 타입 T의 값을 받아 타입 R의 결과를 반환합니다. 한 타입을 다른 타입으로 매핑하는 데 적합합니다.
  • 추상 메서드: R apply(T t)

예시 – String을 길이(Integer)로 변환

Function<String, Integer> length = s -> s.length();
System.out.println(length.apply("hello")); // 5

Function 예시

3️⃣ BiFunction결합기

  • 목적: 두 인자(TU)를 받아 타입 R의 결과를 생성합니다. 두 값을 결합하는 연산에 유용합니다.
  • 추상 메서드: R apply(T t, U u)

예시 – 두 정수를 더하기

BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
System.out.println(add.apply(3, 7)); // 10

BiFunction 예시

4️⃣ Consumer실행기

  • 목적: 타입 T의 값을 받아 아무것도 반환하지 않음(void). 입력을 “소비”하여 동작을 수행합니다.
  • 추상 메서드: void accept(T t)

예시 – 콘솔에 메시지 출력

Consumer<String> printer = msg -> System.out.println(msg);
printer.accept("Hello, Lambda!");

Consumer 예시

TL;DR

  • Lambda expressions 은 최소한의 구문으로 익명 함수를 작성할 수 있게 합니다.
  • 이들은 항상 functional interface 를 대상으로 합니다 — 단일 추상 메서드를 가진 인터페이스.
  • java.util.function 패키지는 가장 유용한 인터페이스들을 제공하며, 특히 Predicate, Function, BiFunction, Consumer 가 있습니다.

보너스: Supplier (제공자)

“Big Four” 중 하나는 아니지만, Supplier는 동일하게 중요합니다.

  • 목적: 입력을 받지 않고 타입 T의 단일 결과를 반환합니다. 값을 제공합니다.

  • 추상 메서드:

    T get();

예제 – 랜덤 숫자 생성

Supplier<Integer> randomNum = () -> new Random().nextInt(100);
System.out.println(randomNum.get());

Random number supplier example

왜 람다를 사용해야 할까?

  • Concise code – 보일러플레이트가 줄어들고 비즈니스 로직에 더 집중할 수 있습니다.
  • Readability – 특히 스트림과 함께 사용할 때 일반 영어처럼 읽히는 경우가 많습니다.
  • Functional programming – Java에서 보다 함수형 스타일의 프로그래밍을 가능하게 합니다.
  • Stream API integration – 람다는 강력한 Java Stream API의 핵심으로, 우아한 데이터 처리를 가능하게 합니다.
Back to Blog

관련 글

더 보기 »

SPRING BOOT 예외 처리

Java & Spring Boot 예외 처리 노트 1. Exception이란? Exception = 프로그램의 정상 흐름을 방해하는 원하지 않는 상황. 예외 처리의 목표...