개발공부/spring boot

[java] Optional - Optional의 매핑 메소드

기억지기 개발자 2023. 10. 24. 12:55

🏕️상황

  • Optional을 사용해야 하는 상황에서 코드를 좀 더 간결하게 하고자 하는 방법을 찾다가 발견한 것이 Optional의 map 함수였다.
  • map 함수라고 하면 java 컬렉션의 map 함수만 생각이 나서 의아했다... '그 map 함수가 optional에서도 연산을 수행하나...?'라는 생각이 들었다.
  • 알아보니 optional 객체의 map() 함수가 따로 존재했던 것이다!!!
  • 그래서 오늘은 아래의 주제에 대해 알아보려고 한다.

 

Optional의 매핑 메소드

 

optional의 매핑 메서드는 map() 및 flatMap() 이렇게 두개의 주요 메소드를 포함한다.

이러한 메소드를 사용해서 Optional 안의 값을 변환하거나 매핑할 수 있다.

 

💚map() 메소드

  • Optional 안의 값을 변환하려는 경우 사용된다.
  • 반환 값은 또 다른 optional으로 감싸져 있다.
  • map()을 사용하면 메서드 체이닝도 사용할 수 있다.
  • map 메서드는 Java의 스트림(Stream) API에서 자주 사용되며, 함수를 적용하고 그 결과를 스트림의 각 요소에 적용한 후 새로운 스트림을 반환하는 메서드이다.  map 메서드의 원래 모양은 다음과 같다.
<R> Stream<R> map (Function<? super T, ? extends R> mapper)
import java.util.Optional;

public class OptionalMappingExample {
    public static void main(String[] args) {
    	// Optional.of 메소드는 주어진 값을 가지는 Optional 인스턴스를 생성한다.
        Optional<String> original = Optional.of("Hello, World!");

        // map 메소드를 사용하여 문자열을 대문자로 변환
        Optional<String> result = original.map(str -> str.toUpperCase());

        // 변환된 결과 출력
        result.ifPresent(System.out::println);
    }
}

 

💚flatMap() 메소드

  • Optional 안의 값을 다른 Optional로 감싸지 않고 직접 반환하려는 경우 사용된다.
  • 주로 중천 된 Optional에서 값을 추출하고자 할 때 유용하다.
import java.util.Optional;

public class OptionalFlatMappingExample {
    public static void main(String[] args) {
        Optional<String> original = Optional.of("Hello, World!");

        // flatMap 메소드를 사용하여 문자열을 나누고 다시 Optional로 감싸지 않음
        Optional<String> result = original.flatMap(str -> Optional.of(str.split(",")[0]));

        // 결과 출력
        result.ifPresent(System.out::println);
    }
}

 

 

⭐실제 나의 코드에 적용시킨 모습(활용코드)

// map 함수 적용전 모습

Optional<FeedbackBoard> feedbackOptional = repository.findById(id);

            if (feedbackOptional.isPresent()) {
                FeedbackBoard feedback = feedbackOptional.get();

                if (user.getId() == feedback.getUser().getId() || user.getRole() == 1) {
                    repository.delete(feedback);

                    return ResponseDTO.success("Feedback deleted successfully.");
                } else {
                    return ResponseDTO.fail("Unauthorized", "You are not authorized to delete this feedback.");
                }
// Optional의 map 함수를 활용하여 리팩토링 후 

Optional<FeedbackBoard> feedbackOptional = repository.findById(id);

            return feedbackOptional.map(feedback -> {
                if (user.getId() == feedback.getUser().getId() || user.getRole() == 1) {
                    return action.apply(feedback);
                } else {
                    return ResponseDTO.fail("Unauthorized", "You are not authorized to access this feedback.");
                }
            }).orElseGet(() -> ResponseDTO.fail("Not Found", "Feedback with ID " + id + " not found."));

 

→복잡하게 if문을 사용하지 않고도 동일한 결과를 얻을 수 있었다.

 

 

💖느낀 점

자바를 거의 처음 접할 때 처음으로 자바 문법 공부를 시작했는데 그게 거의 2년 전인 거 같다.

그때 그 문법 내용에 Optional의 매핑 메서드가 있었을 텐데 그 당시에는 직접적으로 사용할 일이 없다 보니 필요성을 그다지 느끼지 못하고 지나감 + 오래되어 기억이 안 남.

그래서 spring boot를 통해 다양한 기능을 개발해 본 시점에서 다시금 기초 자바 문법을 공부해야겠다고 생각하였다.😂😂