티스토리 뷰

JAVA

map vs flatMap in stream

kkoon9 2022. 2. 4. 11:44

현재 진행중인 사이드 프로젝트에서 사용하는 WebFlux를 분석하면서 정리한 글입니다.

 

자바에서 Stream 인터페이스 메서드인 map()과 flatMap()는 중개 오퍼레이션 역할을 수행합니다.

중개 오퍼레이션이므로 메소드 출력으로 다른 스트림을 반환합니다.

map()과 flatMap()은 모두 변환 및 매핑 작업에 사용됩니다.

map()은 하나의 입력 값에 대해 하나의 출력을 생성하는 반면, flatMap()은 각 입력 값에 대해 출력으로 임의의 수의 값을 생성합니다(0 이상).

  • R : 새 스트림의 요소 타입
  • 스트림 : 인터페이스
  • T : 스트림 요소의 타입
  • mapper : 각 요소에 적용되는 상태 비저장 함수

map(), flatMap() 둘 다 새 스트림을 반환합니다.

map

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

map()은 특정 컬렉션의 요소를 특정 함수에 매핑한 다음 업데이트된 결과를 포함하는 스트림을 반환해야 하는 곳에서 사용할 수 있습니다.

map 같은 경우는 A라는 Container 타입으로 둘러 쌓인 원소를 꺼내서 처리를 해준 뒤, 다시 A Container 타입으로 감싸는 역할을 수행합니다.

ex) 목록의 모든 요소에 3을 곱하고 업데이트된 목록을 반환합니다.

flatMap

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

map()으로는 문자열을 flatten 혹은 transform 할 수 없기 때문에 이와 같은 작업이 필요할 때에는 flatMap()을 사용합니다.

ex) 문자열 목록에 있는 모든 문자열의 첫 번째 문자를 가져오고 스트림 형식으로 결과를 반환합니다.

다음 코드를 예로 들어보겠습니다.

@GetMapping
public Mono<String> rest(int idx) {
		Mono<ClientResponse> res = client.get().uri(URL1, idx).exchange();
		Mono<Mono<String>> body = res.map(clientResponse -> clientResponse.bodyToMono(String.class));

위 body처럼 map으로 처리하게 되면 Mono에 감싸진 Mono<String>를 얻게 됩니다.

그렇기 때문에 flatMap을 사용해야 합니다.

flatMap은 A라는 Container 타입으로 감싸는 역할을 수행하지 않기 때문입니다.

map example code

import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
class Main {
    
    public static void main(String[] args)
    {
        // making the array list object
        ArrayList<String> fruit = new ArrayList<>();
        fruit.add("Apple");
        fruit.add("mango");
        fruit.add("pineapple");
        fruit.add("kiwi");
        System.out.println("List of fruit-" + fruit);
        
        // lets use map() to convert list of fruit
        List list = fruit.stream()
                        .map(s -> s.length())
                        .collect(Collectors.toList());
        System.out.println("List generated by map-" + list);
    }
}

// 실행 결과
List of fruit-[Apple, mango, pineapple, kiwi]
List generated by map-[5, 5, 9, 4]

flatMap example code

import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
class GFG {
    public static void main(String[] args)
    {
        // making the arraylist object of List of Integer
        List<List<Integer> > number = new ArrayList<>();
        
        // adding the elements to number arraylist
        number.add(Arrays.asList(1, 2));
        number.add(Arrays.asList(3, 4));
        number.add(Arrays.asList(5, 6));
        number.add(Arrays.asList(7, 8));
        
        System.out.println("List of list-" + number);
        
        // using flatmap() to flatten this list
        List<Integer> flatList
            = number.stream()
                  .flatMap(list -> list.stream())
                  .collect(Collectors.toList());
        
        // printing the list
        System.out.println("List generate by flatMap-"
                           + flatList);
    }
}

// 실행 결과
List of list-[[1, 2], [3, 4], [5, 6], [7, 8]]
List generate by flatMap-[1, 2, 3, 4, 5, 6, 7, 8]

reference

Difference Between map() And flatMap() In Java Stream - GeeksforGeeks

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html

'JAVA' 카테고리의 다른 글

java에서 멀티쓰레드 [2] Executors와 ExecutorService  (0) 2022.02.07
java에서 멀티쓰레드 [1] Thread와 Runnable  (0) 2022.02.07
Consumer  (0) 2022.02.04
Disposable  (0) 2022.02.04
[면접] String, StringBuffer, StringBuilder 차이 ?  (0) 2020.10.06
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함