[Java] 람다 표현식과 함수형 인터페이스 파헤치기

2026. 4. 23. 19:50·Language/Java

* 개념 복습과 학습 정도를 파악하고자 포스팅합니다!
* Claude, ChatGPT를 활용하여 이미지를 생성하고 활용합니다.

 

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

1. 람다가 왜 나왔을까?

Java 8 이전엔 함수를 값처럼 전달하려면 익명 클래스를 사용해야 했어요. 이로 인해 코드가 장황하고 읽기 힘들다는 단점이 있었죠!

List<String> names = Arrays.asList("Charlie", "Alice", "Bob");

Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});

 

람다가 도입되면서 아래 코드처럼 바뀝니다.

Collections.sort(names, (a, b) -> a.compareTo(b));

// 더 줄이면
names.sort(String::compareTo);

같은 동작을 하는 코드가 7줄에서 1줄로 줄었죠?

람다의 핵심은 함수를 값처럼 다루는 것입니다.


2. 람다 문법 해부하기

  (a, b)        ->         { 본 문 }
매개변수   화살표     실행 코드

 

파라미터 없음

() -> System.out.println("Hello")

 

파라미터 1개

x -> x * x

 

파라미터 1개 (괄호 생략)

name -> "Hello, " + name

 

파라미터 2개

(a, b) -> a + b

 

본문 여러 줄

(a, b) -> { int sum = a + b; return sum; }

 

타입 명시

(String s, int n) -> s.repeat(n)

 

생략 규칙

// 타입 생략 가능
(String a, String b) -> a + b // 생략 전
(a, b) -> a + b              // 생략 후

// 괄호 생략(1개만) 가능
(x) -> x * 2    // 생략 전
x -> x * 2      // 생략 후

// 중괄호 및 return 생략 가능
(a, b) -> { return a + b; } // 생략 전
(a, b) -> a + b            // 생략 후

3. 함수형 인터페이스?

람다를 담는 그릇이 바로 함수형 인터페이스입니다.

추상 메서드가 딱 하나인 인터페이스를 함수형 인터페이스라 부르는데요!

@FunctionalInterface 어노테이션을 붙이면 컴파일러가 규칙을 검증해줍니다.

@FunctionalInterface
public interface MyFunction {
    int apply(int a, int b); // 추상 메서드 딱 하나

    // default, static 메서드는 여러 개 있어도 OK
    default void describe() {
        System.out.println("함수형 인터페이스");
    }
}

// 람다로 구현
MyFunction add = (a, b) -> a + b;
MyFunction mul = (a, b) -> a * b;

add.apply(3, 4); // 7
mul.apply(3, 4); // 12

4. Java 표준 함수형 인터페이스 4가지

Java가 java.util.function패키지에 미리 만들어 놓은 인터페이스들이에요.

직접 만들 필요 없이 이걸 쓰면 됩니다.

//Function<T, R>
Function<String, Integer> len = s -> s.length();
len.apply("Hello"); // 5

Function<String, String> upper = String::toUpperCase;
upper.apply("hello"); // HELLO;

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

//Consumer<T>
Consumer<String> print = s -> System.out.println(s);
print.accept("Hello"); // Hello 출력

//Supplier<T>
Supplier<String> greeting = () -> "Hello";
greeting.get(); // Hello

5. 메서드 참조 (Method Reference)

람다를 더 간결하게 쓰는 방법입니다!

람다가 단순히 기존 메서드를 호출하기만 한다면 : : 문법으로 줄일 수 있습니다.

List<String> names = List.of("Charlie", "Alice", "Bob");

// 정적 메서드 참조
Function<String, Integer> parse = Integer::parseInt;

// 임의 객체 인스턴스 메서드 참조
names.stream()
     .map(String::toUpperCase)  // s -> s.toUpperCase()
     .forEach(System.out::println); // s -> System.out.println(s)

// 특정 인스턴스 메서드 참조
String prefix = "Hello, ";
Function<String, String> greet = prefix::concat;
greet.apply("Alice"); // "Hello, Alice"

// 생성자 참조
Supplier<ArrayList<String>> listFactory = ArrayList::new;
ArrayList<String> newList = listFactory.get();

// 파라미터 있는 생성자 참조
Function<String, StringBuilder> sbFactory = StringBuilder::new;
StringBuilder sb = sbFactory.apply("초기값");

7. 함수 합성 (Function Composition)

함수형 인터페이스에는 함수를 조합하는 메서드가 내장되어 있습니다.

Function<Integer, Integer> times2  = n -> n * 2;
Function<Integer, Integer> plus10  = n -> n + 10;

// andThen — 왼쪽 먼저 실행 후 오른쪽
Function<Integer, Integer> times2ThenPlus10 = times2.andThen(plus10);
times2ThenPlus10.apply(5); // (5 * 2) + 10 = 20

// compose — 오른쪽 먼저 실행 후 왼쪽
Function<Integer, Integer> plus10ThenTimes2 = times2.compose(plus10);
plus10ThenTimes2.apply(5); // (5 + 10) * 2 = 30

// Predicate 조합
Predicate<Integer> isPositive = n -> n > 0;
Predicate<Integer> isEven = n -> n % 2 == 0;

Predicate<Integer> isPositiveEven = isPositive.and(isEven);
isPositiveEven.test(4);  // true
isPositiveEven.test(-2); // false
isPositiveEven.test(3);  // false

Predicate<Integer> isPositiveOrEven = isPositive.or(isEven);
isPositiveOrEven.test(-2); // true (짝수라서)

Predicate<Integer> isNegative = isPositive.negate();
isNegative.test(-3); // true

8. 예제

람다를 활용한 전략 패턴

람다가 나오기 전에는 전략 패턴을 구현하려면 클래스를 여러 개 만들어야 했죠.

람다로 훨씬 간결하게 구현할 수 있습니다.

할인 전략을 람다로 표현하기
@FunctionalInterface
interface DiscountPolicy {
    double apply(double price);
}

public class Order {
    private double price;
    private DiscountPolicy policy;

    public Order(double price, DiscountPolicy policy) {
        this.price = price;
        this.policy = policy;
    }

    public double finalPrice() {
        return policy.apply(price);
    }
}

// 사용 — 클래스 없이 람다로 전략을 바로 주입
DiscountPolicy none = price -> price;
DiscountPolicy ten = price -> price * 0.9;    // 10% 할인
DiscountPolicy fixed = price -> price - 1000;   // 1000원 할인
DiscountPolicy vip = price -> price * 0.7;    // 30% 할인

Order o1 = new Order(10000, ten);
Order o2 = new Order(10000, vip);

System.out.println(o1.finalPrice()); // 9000.0
System.out.println(o2.finalPrice()); // 7000.0

// 동적으로 전략 선택
String grade = "VIP";
DiscountPolicy policy = switch (grade) {
    case "VIP" -> price -> price * 0.7;
    case "GOLD" -> price -> price * 0.85;
    default -> price -> price;
};

핵심 정리

아무래도 람다의 핵심은 코드를 값처럼 전달하는 것인듯 하죠?

함수형 인터페이스가 그릇 역할을 하고, 메서드 참조는 람다를 더 간결하게 줄이는 문법입니다.

람다는 스트림 API의 근간이 되기 때문에 확실하게 이해하고 넘어가야 할 것 같습니다!

'Language > Java' 카테고리의 다른 글

[Java] Enum 파헤치기  (0) 2026.04.25
[Java] 스트림 API(Stream API) 완전히 파헤치기  (0) 2026.04.23
[Java] 제네릭(Generic) 완전히 파헤치기  (0) 2026.04.23
[Java] 컬렉션 프레임워크  (0) 2026.04.23
[Java] 예외 처리 (Exception Handling)  (0) 2026.04.23
'Language/Java' 카테고리의 다른 글
  • [Java] Enum 파헤치기
  • [Java] 스트림 API(Stream API) 완전히 파헤치기
  • [Java] 제네릭(Generic) 완전히 파헤치기
  • [Java] 컬렉션 프레임워크
BackendInho
BackendInho
항상 열정적으로 부딪히고 깨닫는 주니어 백엔드 개발자의 여정을 기록합니다!
  • BackendInho
    Inho.devlog
    BackendInho
  • 전체
    오늘
    어제
    • 분류 전체보기 (41)
      • TIL (0)
      • Language (21)
        • Java (21)
      • Backend (8)
        • Spring (8)
      • Database (0)
        • SQL (0)
      • CS (8)
        • Computer Structure (2)
        • Network (2)
        • OS (1)
        • Data Structure & Algorithms (3)
      • Devops (0)
        • Docker & Kubernetes (0)
      • Coding-Test (1)
        • Programmers (3)
        • LeatCode (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    API
    CS
    HTTP
    java
    REST
    REST API
    Spring
    Spring Boot
    Web
    공간복잡도
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
BackendInho
[Java] 람다 표현식과 함수형 인터페이스 파헤치기
상단으로

티스토리툴바