공부/함수형프로그래밍

map()과 flatMap()을 알고 쓰자

2021. 10. 10. 01:35

자바로 개발하면서 map과 flatMap을 종종 사용하였는고 map과 flatMap에 대해 이렇게 생각하고 있었다.

map은 컬렉션의 반복을 위해 사용하는 것이고 flatMap은 2차원을 1차원으로 만드는 것이지

그러나 이것은 대단히 잘못 알고 있었던 것이었다.

 

 

결론부터 말하자면 Optional 클래스의 map과 flatMap 메서드는 다음과 같은 역할을 한다.

// map을 이용하여 Optional<String> -> Optional<Integer>로 변경
Optional<String> stringOne = Optional.of("1");
Optional<Integer> integerOne = stringOne.map(s -> Integer.parseInt(s));

// flatMap을 이용하여 Optional<String> -> Optional<Integer>로 변경
Optional<String> stringTwo = Optional.of("2");
Optional<Integer> integerTwo = stringTwo.flatMap(s -> Optional.of(Integer.parseInt(s)));

// flatMap을 이용하여 Optional<Optional<Integer>> -> Optional<Integer>로 변경
Optional<Optional<Integer>> nestedOptional = Optional.of(Optional.of(3));
Optional<Integer> optionalTree = nestedOptional.flatMap(i -> i);

 

 

조금 더 자세히 살펴보면

먼저 Optional 클래스의 map 매서드이다.

마지막 라인을 보면 mapper.apply(value) 값을 Optional로 감싸서 반환하는 것을 확인할 수 있다.

매개변수 mapper의 타입 Function 클래스는 다음과 같다.

apply메서드는 T타입을 받아서 R타입으로 반환해주는 메서드인 것을 알 수 있다.

그래서 String 타입을 받아 Integer 타입을 반환하는 Integer.parseInt 메서드를 매개변수 mapper로 사용하면 Optional<String> -> Optional<Integer>로 변환할 수 있다.

여기서 알 수 있는 map의 특징은 무조건 mapper의 반환 값을 Optional로 감싼다는 것이다.

이 경우 문제는 매개변수 mapper에 Optional 타입을 반환하는 매개변수를 넣는다면 map의 반환 값은 Optional<Optional<?>> 이 되는 것이다.

이런 경우를 해결할 수 있는 것이 flatMap이다.

 

 

다음은 Optional 클래스의 flatMap 메서드이다.

map 메서드와는 다르게 매개변수 mapper의 apply 메서드가 Optional<? extends U> 타입인 것을 알 수 있다.

즉 mapper 메서드에서 Optional 타입을 반환한다는 점이 map과 차이이다.

그래서 Optional<String> -> Optional<Integer> 이렇게 변환하기 위해서는 매개변수 mapper를 String 타입을 받아 Optional<Integer> 타입을 반환하는 메서드로 넣어줘야 한다.

그래서 다음과 같이 되는 것이다.

그래서 중첩된 구조도 해결할 수 있다.

 

 

평소에 생각 없이 쓰던 map과 flatMap에 대해서 공부하게 되어 재미있었다. 자주 쓰는 기능들을 제대로 숙지하고 사용하는 습관을 들이면 좋을 것 같다.

 

 

 

 

반응형