개발(React | Java)/자바 기초 | 문법

📘 Java 람다 & Stream (3) 람다식(Lambda) & Stream 완전 이해 — 실무 컬렉션 처리의 핵심

dev-parrot 2025. 12. 10. 16:12

 

람다식과 스트림은 Java 8에서 등장한 기능으로,
복잡한 반복문을 훨씬 간결하고 직관적으로 처리할 수 있게 해줍니다.

“for문 10줄 → 스트림 한 줄”로 줄어드는 강력한 문법입니다.
실무에서 컬렉션 다룰 때 반드시 사용되므로 꼭 이해해야 합니다.


📌 목차

  1. 람다식(Lambda)란?
  2. 람다 기본 문법
  3. 함수형 인터페이스(Functional Interface)
  4. Stream이란?
  5. Stream 주요 기능(map, filter, sorted 등)
  6. collect로 결과 모으기
  7. 실전 예제 (리스트 필터링/변환/정렬)
  8. 자주 하는 실수
  9. 대표 태그

1️⃣ 람다식(Lambda)란?

람다식은 익명 함수를 간단하게 표현한 문법입니다.

기존 익명 클래스:

Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello");
    }
};

 

람다식:

Runnable r = () -> System.out.println("Hello");

 

➡ 코드가 훨씬 간결해짐.


2️⃣ 람다 기본 문법

 
(매개변수) -> { 실행문 }

✔ 예: 숫자 두 개 더하기

(int a, int b) -> { return a + b; }
✔ 매개변수 타입 생략 가능
(a, b) -> a + b

✔ 매개변수 1개면 괄호 생략 가능

x -> x * 2

✔ 실행문 1줄 → 중괄호 return 생략 가능

() -> System.out.println("Hi");
x -> x * 2

 

 

3️⃣ 함수형 인터페이스(Functional Interface)

람다식이 사용되기 위해서는 반드시
추상 메서드가 1개인 인터페이스가 필요합니다.

대표 예:

  • Runnable
  • Callable
  • Comparator
  • Consumer
  • Predicate
  • Function

예:

@FunctionalInterface
interface MyFunc {
    int run(int x);
}

 

람다 사용:

MyFunc f = x -> x * 10;
System.out.println(f.run(5)); // 50

 

4️⃣ Stream이란?

Stream은 컬렉션(List, Set)을 데이터 흐름처럼 처리할 수 있게 하는 도구입니다.

특징:

✔ 반복문 없이 선언형 코드
✔ map(변환), filter(필터링), sorted(정렬) 등 지원
✔ 병렬 처리(parallelStream) 가능
✔ 원본 컬렉션 변경 없음


5️⃣ Stream 기본 흐름

list.stream()
    .filter(x -> x > 10)
    .map(x -> x * 2)
    .sorted()
    .collect(Collectors.toList());

 

 

구조는 항상

stream → 중간 연산(map/filter 등) → 최종 연산(collect 등)


✨ 주요 기능 정리

✔ filter(조건으로 걸러내기)

list.stream()
    .filter(x -> x % 2 == 0)

✔ map(값 변환)

list.stream() .map(x -> x * 2)

✔ sorted(정렬)

list.stream() .sorted()

✔ distinct(중복 제거)

list.stream() .distinct()

✔ limit / skip

list.stream().limit(3) // 상위 3개 
list.stream().skip(2) // 처음 2개 건너뛰기

✔ collect(결과를 모아서 컬렉션으로 반환)

.collect(Collectors.toList());

6️⃣ 실전 예제 모음

✔ 1) 짝수만 골라서 출력

 
List<Integer> nums = List.of(1,2,3,4,5,6);

nums.stream()
    .filter(n -> n % 2 == 0)
    .forEach(System.out::println);

✔ 2) 모든 값을 2배로 변환 후 리스트로 반환

 
List<Integer> result = nums.stream()
    .map(n -> n * 2)
    .collect(Collectors.toList());

✔ 3) 문자열 리스트 정렬

ㄷㅇ
List<String> sorted = names.stream()
    .sorted()
    .collect(Collectors.toList());​

✔ 4) 객체 리스트에서 특정 필드만 추출 (중요!)

 
List<User> users = ...
List<String> names = users.stream()
    .map(User::getName)
    .collect(Collectors.toList());

✔ 5) 객체 리스트에서 나이 20 이상 필터링

users.stream()
    .filter(u -> u.getAge() >= 20)
    .forEach(System.out::println);

 

7️⃣ 자주 하는 실수

❌ stream()은 1회 사용 후 재사용 불가

스트림은 일회성.

❌ map과 filter 순서를 혼동

  • filter: 조건
  • map: 변환

❌ 원본 List가 바뀌는 줄 아는 경우

Stream은 원본 변경 없음.


8️⃣ 마무리

이번 글에서는 Java 실무 개발에서 가장 중요한 문법인

✔ 람다(Lambda) 문법
✔ 함수형 인터페이스
✔ Stream 개념
✔ filter, map, sorted, collect
✔ 실전 컬렉션 처리 예제

를 정리했습니다.

이제 이 문법들을 알고 있다면 Spring 코드도 10배 더 쉽게 이해할 수 있어요.

 

📘 다음 글 예고

👉 Spring Boot 입문 (4) — 처음 만드는 스프링 프로젝트, 구조 완전 이해