[Java 개념노트 55] 람다식이란 무엇인가?
안녕하세요. Java 개념노트 시리즈 쉰다섯 번째 글입니다.
지난 글에서는 제네릭의 타입 범위를 제한하는 제한된 제네릭과 와일드카드에 대해 정리했습니다. 이번 글에서는 자바에서 코드를 더 짧고 간결하게 표현할 수 있는 람다식에 대해 알아보겠습니다.
람다식은 처음 보면 () -> 모양 때문에 낯설게 느껴질 수 있습니다. 하지만 핵심은 간단합니다. 메서드처럼 실행할 수 있는 코드를 짧게 표현하는 문법입니다.
1. 람다식이란?
람다식은 메서드처럼 동작하는 코드를 짧게 표현하는 문법입니다.
자바에서는 람다식을 사용해서 인터페이스의 메서드 구현을 간결하게 작성할 수 있습니다. 특히 추상 메서드가 하나뿐인 인터페이스와 함께 사용됩니다.
쉽게 말하면
람다식은 “이 메서드가 실행되면 이런 일을 해라”라는 코드를 짧게 적는 방법입니다.
2. 람다식 기본 형태
람다식의 기본 형태는 다음과 같습니다.
(매개변수) -> {
실행할 코드
}
예를 들어 매개변수 없이 문장 하나를 출력하는 람다식은 다음처럼 작성할 수 있습니다.
() -> {
System.out.println("Hello Lambda");
}
화살표 -> 왼쪽에는 매개변수를 적고, 오른쪽에는 실행할 코드를 적습니다.
3. 람다식은 혼자 사용할 수 없다
람다식은 아무 곳에나 단독으로 작성해서 사용하는 문법이 아닙니다. 람다식은 보통 함수형 인터페이스 타입에 대입해서 사용합니다.
// () -> System.out.println("Hello");
// 이렇게 단독으로만 쓰면 사용할 대상이 없습니다.
람다식은 “어떤 인터페이스의 어떤 메서드를 구현하는 코드인지”가 정해져야 사용할 수 있습니다.
4. 함수형 인터페이스란?
함수형 인터페이스는 추상 메서드를 하나만 가진 인터페이스입니다.
interface Hello {
void say();
}
위 인터페이스에는 추상 메서드가 say() 하나만 있습니다. 이런 인터페이스는 람다식으로 구현할 수 있습니다.
핵심 포인트
람다식은 추상 메서드가 하나뿐인 인터페이스를 간단하게 구현할 때 사용합니다.
5. 람다식 기본 예제
매개변수 없이 문장을 출력하는 람다식을 만들어보겠습니다.
public class Main {
public static void main(String[] args) {
Hello hello = () -> {
System.out.println("안녕하세요. 람다식입니다.");
};
hello.say();
}
}
interface Hello {
void say();
}
실행 결과는 다음과 같습니다.
안녕하세요. 람다식입니다.
Hello 인터페이스의 say() 메서드가 람다식으로 구현되었습니다. hello.say()를 호출하면 람다식 오른쪽의 코드가 실행됩니다.
6. 익명 구현 객체와 람다식 비교
람다식은 익명 구현 객체를 더 짧게 표현한 형태로 이해할 수 있습니다.
익명 구현 객체
Hello hello = new Hello() {
@Override
public void say() {
System.out.println("안녕하세요.");
}
};
람다식
Hello hello = () -> {
System.out.println("안녕하세요.");
};
두 코드는 비슷한 역할을 합니다. 람다식을 사용하면 반복되는 코드가 줄어들어 더 간결하게 표현할 수 있습니다.
7. 실행 코드가 한 줄이면 중괄호를 생략할 수 있다
람다식의 실행 코드가 한 줄이면 중괄호 { }를 생략할 수 있습니다.
Hello hello = () -> System.out.println("안녕하세요.");
hello.say();
실행 결과는 다음과 같습니다.
안녕하세요.
한 줄짜리 람다식은 이렇게 짧게 작성할 수 있습니다.
8. 매개변수가 있는 람다식
람다식은 매개변수를 받을 수도 있습니다.
public class Main {
public static void main(String[] args) {
MessagePrinter printer = (String message) -> {
System.out.println(message);
};
printer.print("Java Lambda");
}
}
interface MessagePrinter {
void print(String message);
}
실행 결과는 다음과 같습니다.
Java Lambda
MessagePrinter 인터페이스의 print(String message) 메서드를 람다식으로 구현했습니다.
9. 매개변수 타입 생략하기
람다식에서는 매개변수 타입을 생략할 수 있습니다. 자바가 인터페이스의 메서드 형태를 보고 타입을 추론하기 때문입니다.
MessagePrinter printer = message -> System.out.println(message);
printer.print("타입을 생략한 람다식");
위 코드에서 message는 String 타입입니다. 하지만 인터페이스의 메서드가 void print(String message)이기 때문에 람다식에서 타입을 생략할 수 있습니다.
10. 매개변수가 하나면 괄호도 생략할 수 있다
매개변수가 하나이고 타입을 생략하면 괄호 ( )도 생략할 수 있습니다.
MessagePrinter printer = message -> System.out.println(message);
하지만 매개변수가 두 개 이상이면 괄호를 생략할 수 없습니다.
Calculator calculator = (a, b) -> a + b;
기억하기
매개변수가 하나일 때만 괄호를 생략할 수 있습니다. 매개변수가 없거나 두 개 이상이면 괄호가 필요합니다.
11. 값을 반환하는 람다식
람다식은 값을 반환할 수도 있습니다.
public class Main {
public static void main(String[] args) {
Calculator calculator = (a, b) -> {
return a + b;
};
int result = calculator.add(10, 20);
System.out.println(result);
}
}
interface Calculator {
int add(int a, int b);
}
실행 결과는 다음과 같습니다.
30
Calculator 인터페이스의 add() 메서드는 int를 반환합니다. 그래서 람다식 안에서 return a + b;를 작성했습니다.
12. 반환 코드가 한 줄이면 return을 생략할 수 있다
반환하는 코드가 한 줄이면 중괄호와 return을 생략할 수 있습니다.
Calculator calculator = (a, b) -> a + b;
int result = calculator.add(10, 20);
System.out.println(result);
위 람다식은 아래 코드와 비슷한 의미입니다.
Calculator calculator = (a, b) -> {
return a + b;
};
짧게 쓸 수 있지만, 코드가 복잡해지면 중괄호를 사용하는 편이 더 읽기 쉬울 수 있습니다.
13. 중괄호를 쓰면 return을 명확히 작성해야 한다
반환값이 있는 람다식에서 중괄호를 사용했다면 return을 작성해야 합니다.
올바른 예
Calculator calculator = (a, b) -> {
return a + b;
};
잘못된 예
Calculator calculator = (a, b) -> {
a + b; // 오류 발생
};
중괄호를 사용하면 실행 블록이 되므로 반환값이 필요한 경우 return을 명확히 작성해야 합니다.
14. 람다식 문법 정리
람다식 문법을 정리하면 다음과 같습니다.
| 형태 | 예시 | 설명 |
| 매개변수 없음 | () -> 실행문 |
괄호 필요 |
| 매개변수 1개 | x -> 실행문 |
타입 생략 시 괄호 생략 가능 |
| 매개변수 2개 이상 | (a, b) -> 실행문 |
괄호 필요 |
| 실행문 여러 줄 | (a, b) -> { ... } |
중괄호 사용 |
| 한 줄 반환 | (a, b) -> a + b |
return 생략 가능 |
15. @FunctionalInterface
함수형 인터페이스에는 @FunctionalInterface를 붙일 수 있습니다.
@FunctionalInterface
interface Calculator {
int add(int a, int b);
}
이 어노테이션을 붙이면 해당 인터페이스가 추상 메서드 하나만 가지는지 컴파일러가 확인해줍니다. 만약 추상 메서드를 두 개 작성하면 오류가 발생합니다.
@FunctionalInterface
interface Calculator {
int add(int a, int b);
// int minus(int a, int b); // 오류 발생
}
람다식으로 사용할 인터페이스라면 @FunctionalInterface를 붙여두면 실수를 줄일 수 있습니다.
16. 람다식과 Runnable
자바에서 자주 만나는 함수형 인터페이스 중 하나가 Runnable입니다. Runnable은 매개변수도 없고 반환값도 없는 run() 메서드를 가집니다.
public class Main {
public static void main(String[] args) {
Runnable task = () -> {
System.out.println("작업을 실행합니다.");
};
task.run();
}
}
실행 결과는 다음과 같습니다.
작업을 실행합니다.
Runnable은 이미 자바에서 제공하는 인터페이스입니다. 람다식으로 run() 메서드의 실행 내용을 작성했습니다.
17. ArrayList forEach와 람다식
컬렉션의 forEach() 메서드에서도 람다식을 사용할 수 있습니다.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> subjects = new ArrayList<>();
subjects.add("Java");
subjects.add("Spring");
subjects.add("SQL");
subjects.forEach(subject -> System.out.println(subject));
}
}
실행 결과는 다음과 같습니다.
Java
Spring
SQL
subject -> System.out.println(subject)는 목록의 값을 하나씩 받아 출력하는 람다식입니다.
18. Comparator와 람다식 맛보기
람다식은 정렬 기준을 간단하게 작성할 때도 자주 사용됩니다. 예를 들어 문자열 길이를 기준으로 정렬할 수 있습니다.
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ArrayList<String> words = new ArrayList<>();
words.add("Java");
words.add("SQL");
words.add("Spring");
Collections.sort(words, (a, b) -> a.length() - b.length());
System.out.println(words);
}
}
실행 결과는 다음과 같습니다.
[SQL, Java, Spring]
문자열 길이가 짧은 순서로 정렬되었습니다. (a, b) -> a.length() - b.length()가 정렬 기준 역할을 합니다.
19. 람다식은 코드를 짧게 만들지만 무조건 좋은 것은 아니다
람다식은 코드를 짧게 만들 수 있지만, 너무 복잡한 로직을 한 줄에 몰아넣으면 오히려 읽기 어려워질 수 있습니다.
읽기 쉬운 예
Calculator calculator = (a, b) -> a + b;
복잡해질 수 있는 예
Calculator calculator = (a, b) -> {
int sum = a + b;
int bonus = 10;
return sum + bonus;
};
실행 코드가 여러 줄이거나 조건이 많아지면 메서드로 분리하는 것이 더 깔끔할 수 있습니다. 람다식은 짧고 명확한 동작을 표현할 때 가장 잘 어울립니다.
20. 람다식 전체 예제
이번에는 여러 형태의 람다식을 한 번에 사용하는 예제를 보겠습니다.
public class Main {
public static void main(String[] args) {
Hello hello = () -> System.out.println("람다식 시작");
hello.say();
MessagePrinter printer = message -> System.out.println("메시지: " + message);
printer.print("Java");
Calculator addCalculator = (a, b) -> a + b;
Calculator multiplyCalculator = (a, b) -> a * b;
System.out.println(addCalculator.calculate(10, 20));
System.out.println(multiplyCalculator.calculate(10, 20));
}
}
@FunctionalInterface
interface Hello {
void say();
}
@FunctionalInterface
interface MessagePrinter {
void print(String message);
}
@FunctionalInterface
interface Calculator {
int calculate(int a, int b);
}
실행 결과는 다음과 같습니다.
람다식 시작
메시지: Java
30
200
매개변수가 없는 람다식, 매개변수가 하나인 람다식, 값을 반환하는 람다식을 모두 사용했습니다.
21. 람다식 사용 시 자주 하는 실수
람다식을 처음 배울 때는 아래와 같은 실수를 자주 합니다.
| 실수 | 문제점 | 해결 방법 |
| 추상 메서드가 여러 개인 인터페이스에 람다식 사용 | 어떤 메서드를 구현할지 알 수 없음 | 추상 메서드가 하나인 함수형 인터페이스 사용 |
| 매개변수가 없는데 괄호 생략 | 문법 오류 발생 | () -> 실행문 형태 사용 |
| 매개변수가 두 개인데 괄호 생략 | 문법 오류 발생 | (a, b) -> 실행문 형태 사용 |
| 중괄호를 쓰고 return 누락 | 반환값이 필요한 메서드에서 오류 발생 | { return 값; } 형태 사용 |
| 람다식을 무조건 짧게만 쓰려고 함 | 코드가 오히려 읽기 어려워질 수 있음 | 복잡하면 메서드로 분리 |
22. 직접 연습해보기
아래 코드를 직접 작성하고 실행해보세요.
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) {
ButtonClick click = () -> System.out.println("버튼을 클릭했습니다.");
click.click();
TextChecker checker = text -> text.length() >= 4;
System.out.println(checker.check("Java"));
System.out.println(checker.check("SQL"));
ArrayList<String> words = new ArrayList<>();
words.add("Spring");
words.add("Java");
words.add("SQL");
Collections.sort(words, (a, b) -> a.length() - b.length());
words.forEach(word -> System.out.println(word));
}
}
@FunctionalInterface
interface ButtonClick {
void click();
}
@FunctionalInterface
interface TextChecker {
boolean check(String text);
}
실행 결과는 다음과 같습니다.
버튼을 클릭했습니다.
true
false
SQL
Java
Spring
23. 이번 글 정리
이번 글에서는 코드를 더 짧고 간결하게 표현할 수 있는 람다식에 대해 정리했습니다. 핵심 내용은 다음과 같습니다.
- 람다식은 메서드처럼 실행할 수 있는 코드를 짧게 표현하는 문법이다.
- 람다식의 기본 형태는
(매개변수) -> { 실행 코드 }이다. - 람다식은 함수형 인터페이스와 함께 사용된다.
- 함수형 인터페이스는 추상 메서드가 하나뿐인 인터페이스이다.
- 실행 코드가 한 줄이면 중괄호를 생략할 수 있다.
- 매개변수 타입은 생략할 수 있다.
- 매개변수가 하나일 때는 괄호를 생략할 수 있다.
- 매개변수가 없거나 두 개 이상이면 괄호가 필요하다.
- 반환 코드가 한 줄이면
return을 생략할 수 있다. - 중괄호를 사용하면 반환값이 필요한 경우
return을 작성해야 한다. @FunctionalInterface를 붙이면 함수형 인터페이스 규칙을 확인할 수 있다.- 람다식은
forEach(), 정렬 기준 작성 등에서 자주 사용된다.
한 줄 요약
람다식은 함수형 인터페이스의 추상 메서드 구현을 짧고 간결하게 표현하는 자바 문법입니다.
다음 글 예고
다음 글에서는 [Java 개념노트 56] 함수형 인터페이스 이해하기라는 주제로 Predicate, Consumer, Supplier, Function 같은 자바 기본 함수형 인터페이스를 정리해보겠습니다.
GWDEVELBlog Java 개념노트 시리즈

'Computer Science > Java' 카테고리의 다른 글
| [Java 개념노트 57] 메서드 참조 이해하기 (0) | 2026.07.17 |
|---|---|
| [Java ] 개념노트 56 함수형 인터페이스 이해하기 (0) | 2026.06.18 |
| [Java ] 개념노트 54 제한된 제네릭과 와일드카드 이해하기 (0) | 2026.06.18 |
| [Java ] 개념노트 53 제네릭 클래스와 제네릭 메서드 이해하기 (0) | 2026.06.17 |
| [Java ] 개념노트 52 제네릭이란 무엇인가? (0) | 2026.06.17 |