language/java

[java] map과 flatMap의 차이

아르르르를를르 2022. 6. 9. 23:00

면접질문으로 나왔던 map과 flatMap의 차이점을 복기한다.

Java 8 에서 Optional, stream이 추가되었고 이에 사용될 수 있는 map()와 flatMap() 의 목적이 다르다.

 

Optional에서 Map, flatMap 사용법

다음 예시는 "test"를 대문자로 변환한다.

    Optional<String> s = Optional.of("test");
    Assertions.assertEquals(Optional.of("TEST"), s.map(String::toUpperCase));
    System.out.println(Optional.of("TEST"));	
    //output: Optional[TEST]

 

더 복잡한 경우에 Optional.of() 파라미터값으로 Optional.of()가 반환되는 함수가 들어갔다고 생각해보자.

    assertEquals(Optional.of(Optional.of("STRING")), 
                 Optional.of("string").map(s -> Optional.of("STRING"))
    );

Optional.of() 는 "not null값"만을 취급하므로 NullPointerException이 발생할 수 있다.

이럴 때 flatMap()을 다음과 같이 사용한다.

    assertEquals(Optional.of("STRING"), 
                 Optional.of("string").flatMap(s -> Optional.of("STRING"))
    );

 

 

Stream에서 Map, flatMap 사용법

flatMap() 중복된 스트림을 1차원으로 평면화시킨다.

따라서 중복 구조로 되어있는 리스트를 하나의 stream화 시킬 수 있다.

    List<String> list = Stream.of("a", "b")
        .map(String::toUpperCase)
        .collect(Collectors.toList());
    System.out.println(list); // output: [A, B]

    List<List<String>> list2 = Arrays.asList(
        Arrays.asList("a"),
        Arrays.asList("b"));
    System.out.println(list2); // output: [[a], [b]]

    System.out.println(list2
        .stream()
        .flatMap(Collection::stream)
        .collect(Collectors.toList())); // output: [a, b]