본문 바로가기

Java

Java 람다식 (Lambda Expression)

람다식이란?

람다식은 익명 함수(Anonymous Function)를 생성하기 위한 표현식으로, Java 8부터 도입되었다.

 

기존에 사용하던 익명 클래스를 간결하고 직관적으로 표현할 수 있도록 설계되었다.

함수형 프로그래밍 개념을 자바에 도입한 기능 중 하나로, 코드를 간결하게 작성하고 가독성을 높여준다.

 

(parameters) -> expression
(parameters) -> { statements }

 

  • parameters: 입력 매개변수. 입력 매개변수가 없으면 빈 괄호 () 사용.
  • ->: 람다 연산자(arrow operator).
  • expression/statements: 실행할 코드 블록.

 

람다식의 주요 특징으로는 아래와 같다.

 

  • 익명: 이름이 없는 함수로, 클래스나 메서드 없이도 사용할 수 있다.

  • 간결성: 불필요한 코드 작성을 줄이고 코드를 간결하게 만든다.

  • 함수형 인터페이스와 함께 사용:
    • 람다식은 반드시 단일 추상 메서드(SAM: Single Abstract Method)를 가진 인터페이스에서만 사용할 수 있다.
    • 예: Runnable, Callable, Comparator, 그리고 자바 8의 java.util.function 패키지 내 함수형 인터페이스들.

 

람다식의 예제

기존 익명 클래스

import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer a, Integer b) {
                return a - b;
            }
        };

        System.out.println(comparator.compare(5, 3)); // 출력: 2
    }
}

 

 

 

 

람다식으로 변경

import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        Comparator<Integer> comparator = (a, b) -> a - b;

        System.out.println(comparator.compare(5, 3)); // 출력: 2
    }
}

 

 

매개변수 없는 경우

Runnable runnable = () -> System.out.println("Hello, Lambda!");
runnable.run(); // 출력: Hello, Lambda!

 

 

매개변수 한 개

Consumer<String> consumer = s -> System.out.println(s);
consumer.accept("Hello, World!"); // 출력: Hello, World!

 

 

매개변수 두 개 이상

BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b;
System.out.println(sum.apply(5, 3)); // 출력: 8

 

 

코드 블록 사용

Comparator<Integer> comparator = (a, b) -> {
    System.out.println("Comparing " + a + " and " + b);
    return a - b;
};
System.out.println(comparator.compare(10, 5)); // 출력: Comparing 10 and 5 / 5

 

 

 

람다식과 함수형 인터페이스

함수형 인터페이스란?

  • 단 하나의 추상 메서드만 가진 인터페이스.
  • 람다식은 이러한 함수형 인터페이스를 구현할 때 사용된다.
  • 자바 8에서 @FunctionalInterface 어노테이션을 사용해 함수형 인터페이스임을 명시할 수 있다.

 

사용자 정의 함수형 인터페이스

@FunctionalInterface
interface Calculator {
    int calculate(int a, int b);
}

public class Main {
    public static void main(String[] args) {
        Calculator add = (a, b) -> a + b;
        Calculator multiply = (a, b) -> a * b;

        System.out.println(add.calculate(5, 3));      // 출력: 8
        System.out.println(multiply.calculate(5, 3)); // 출력: 15
    }
}

 

 

자바 제공 함수형 인터페이스

자바 8의 java.util.function 패키지는 다양한 함수형 인터페이스를 제공한다.

 

인터페이스 설명 메서드 시그니처
Function<T, R> 입력값을 받아 출력값을 반환 R apply(T t)
Consumer<T> 입력값을 받아 소비(출력/사용) void accept(T t)
Supplier<T> 입력값 없이 출력값을 반환 T get()
Predicate<T> 입력값을 받아 boolean을 반환 boolean test(T t)
BiFunction<T, U, R> 두 개의 입력값을 받아 출력값 반환 R apply(T t, U u)

 

 

 

람다식과 스트림(Stream) API

람다식은 Stream API와 함께 자주 사용된다.

 

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

        // 스트림과 람다식 사용
        names.stream()
             .filter(name -> name.startsWith("A"))
             .forEach(System.out::println); // 출력: Alice
    }
}

 

 

 

람다식과 메서드 참조

람다식이 간단한 경우, 메서드 참조를 사용할 수 있다.

 

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("Alice", "Bob", "Charlie");

        // 람다식 대신 메서드 참조 사용
        names.forEach(System.out::println); // 출력: Alice, Bob, Charlie
    }
}