Java Stream API - map() vs flatMap() 정복하기

2025. 6. 15. 16:18·Language & Framework/Java
728x90

Java의 Stream API는 데이터를 함수형 스타일로 처리할 수 있는 강력한 도구다.

그중에서도 `map()`과 `flatMap()`은 가장 자주 사용되는 중간 연산자이다.

하지만 두 메서드는 이름이 비슷해 헷갈리기 쉽다.

이번 글에서는 두 메서드의 차이와 활용법을 예제 중심으로 쉽게 정리해보겠다.


🔄 map() - 요소를 변환

`map()`은 스트림의 각 요소를 일대일로 변환할 때 사용한다.

주로 원하는 필드만 추출하거나 특정 형태로 변환할 떄 사용한다.

예시)

  • 각 요소를 새로운 값으로 매핑
  • 변환 결과를 새 스트림으로 반환
  • 내부적으로 `Function<T, R>`이 사용됨

📌 예제 1: 문자열을 대문자로

List<String> names = Arrays.asList("kimcoding", "javalee", "hackerna", "luckyguy");

names.stream()
     .map(String::toUpperCase)
     .forEach(System.out::println);

출력:

KIMCODING
JAVALEE
HACKERNA
LUCKYGUY

 

📌 예제 2: 숫자 변환

List<Integer> numbers = Arrays.asList(1, 3, 6, 9);

numbers.stream()
       .map(n -> n * 3)
       .forEach(System.out::println);

출력:

3
9
18
27

📂 flatMap() - 중첩을 펼치다

`flatMap()`은 중첩된 스트림의 구조를 스트림의 각 요소를 스트림으로 변환하여

그 모든 내부 스트림을 하나로 평탄화(flatten) 한다.

  • 중첩된 구조 해제 (2차원 → 1차원)
  • `Stream<Stream<T>> → Stream<T>`
  • 내부적으로 `Function<T, Stream<R>>` 사용

📌 예제: 중첩 리스트 평탄화

List<List<String>> nestedList = Arrays.asList(
    Arrays.asList("JAVA", "SPRING"),
    Arrays.asList("java", "spring")
);

nestedList.stream()
          .flatMap(Collection::stream)
          .forEach(System.out::println);

출력:

JAVA
SPRING
java
spring

🧠 map() vs flatMap()의 차이점

같은 데이터로 두 방식 비교해보자!

List<String> sentences = Arrays.asList("a b", "c d");

// map 사용
List<Stream<String>> withMap = sentences.stream()
    .map(s -> Arrays.stream(s.split(" ")))   // Stream<Stream<String>>
    .collect(Collectors.toList());

// flatMap 사용
List<String> withFlatMap = sentences.stream()
    .flatMap(s -> Arrays.stream(s.split(" ")))   // Stream<String>
    .collect(Collectors.toList());
  • `map()`을 사용하면 각 문장이 단어 배열로 나뉜다 → Stream<Stream<String>>
    • `"a b"` → `Stream.of("a", "b")`
    • `"c d"` → `Stream.of("c", "d")`
// 출력결과
a
b
c
d
  • `flatMap()`을 사용하면 모든 단어가 하나의 스트림으로 평탄화됨 → Stream<String>
// 출력결과
["a", "b", "c", "d"]

🔍 map() vs flatMap() 비교

항목 `map()` `flatMap()`
목적 요소 변환 중첩된 요소를 펼침
결과 구조 Stream<T> 또는 Stream<Stream<T>> Stream<T>
변환 수 1:1 변환 1:N 변환 + 평탄화
사용 예 문자열 대문자 변환, 수학 연산 리스트 안의 리스트 펼치기, 문장 → 단어

💡 언제 무엇을 써야 할까?

각 요소를 하나의 값으로 변환할 때는?

  • `map()` 메소드 사용!
    • 간단하게 변환할 수 있음(ex. 포맷 변경, 계산 등)

각 요소를 여러 값으로 변환 후 펼칠 때는?

  • `flatMap()` 메소드 사용!
    • 중첩된 구조를 해제할 수 있음(ex. 배열, 리스트)

✏️ 마무리

Java Stream API의 `map()`과 `flatMap()`은 개념이 비슷해 보이지만,

중첩 구조의 유무와 평탄화 여부에 따라 확연히 다르다!

“map()은 변환, flatMap()은 펼친다”

728x90
저작자표시 비영리 변경금지 (새창열림)
'Language & Framework/Java' 카테고리의 다른 글
  • [JAVA] Java Comparator 완전 정복: compare 메서드의 동작 원리
  • HashSet은 어떻게 중복을 제거할까? (내부구조와 중복 체크 원리)
밍구링구리
밍구링구리
밍구리의 실험실 이것저것 배우고 기록을 남깁니다
  • 밍구링구리
    Mingguri Labatory
    밍구링구리
    • 홈
    • 태그
    • 방명록
    • 깃허브
  • 전체
    오늘
    어제
    • 분류 전체보기 (96)
      • Language & Framework (15)
        • Java (3)
        • Vue.js (1)
        • Spring Boot (10)
      • Computer Science (4)
        • Operating System) (0)
        • Database (2)
        • Network (1)
        • Data Structure (0)
        • Algorithm (1)
      • Architecture & Design (7)
      • Cloud & Infra (5)
      • Trouble Shooting (0)
        • 에러 해결 (0)
        • 삽질 기록 (0)
      • 회고 (0)
      • Coding Practice (42)
        • Backjoon (24)
        • LeetCode (6)
        • Programmers (12)
      • Book (0)
      • ETC (21)
        • 블로그 관리 (3)
        • 일상 (1)
        • 후기 (2)
        • 밍구의 실험실 (1)
        • 🤔Study . Question🔍 (14)
      • 부트캠프 (1)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 태그

    골드5
    우선순위큐
    유스케이스
    알고리즘
    퀴즈
    SOLID
    스케일업
    스터디
    dfs
    구현
    코딩테스트
    백준
    level 2
    객체지향
    OOP
    git
    Spring Boot
    테스트케이스
    백트래킹
    백엔드
    vue.js
    코드잇
    투포인터
    스케일아웃
    골드4
    프로그래머스
    문제
    BFS
    그리디
    LeetCode
  • 250x250
  • hELLO· Designed By정상우.v4.10.3
밍구링구리
Java Stream API - map() vs flatMap() 정복하기
상단으로

티스토리툴바