[Java 8] Optional API

홍정완·2022년 6월 15일
0

Java

목록 보기
8/25
post-thumbnail

Optional

  • 오직 값 한 개가 들어있을 수도 없을 수도 있는 컨네이너



  • 자바 프로그래밍에서 NullPointerException을 종종 보게 되는 이유

    • null을 리턴 or null 체크를 깜빡



메서드에서 작업 중 값을 제대로 리턴할 수 없는 경우


  • 예외를 던진다

    • 스택 트레이스로 인한 비용 발생

    • ✅ 스택트레이스는 프로그램이 시작된 시점부터 현재 위치까지의 메서드 호출 목록,
      이는 예외가 어디서 발생했는지 알려주기 위해 JVM이 자동으로 생성

  • null을 리턴

    • ✅ 해당 코드를 사용하는 클라이언트 코드는 주의 필요
  • (자바 8부터) Optional을 리턴

    • ✅ 클라이언트 코드에게 명시적으로 빈값 일 수도 있는 것을 알려주고, 빈 값인 경우에는 처리를 강제



⭐ 주의할 점


  • 리턴 값으로 만 쓰기 권장

  • Optional을 리턴하는 메서드에서 null 리턴 ❌

  • 기본형 Optional을 따로 있다. 👉 Ex) OptionalInt, OptionalLong,...
Optional.of(10);
OptionalInt.of(10); // 권장

  • Collection, Map, Stream Array, Optional은 Opiontal로 감싸지 말 것.

    • 이 자체로 비어있는지 확인할 수 있는 컨테이너 성격의 인스턴스들



Optional API


  • Optional.of()
  • Optional.ofNullable()
  • Optional.empty()

  • Optional 값 확인
    • isPresent()
    • isEmpty() (Java 11부터 제공)

  • Optional에 있는 값 가져오기
    • get()

  • Optional에 값이 있는 경우에 그 값을 가지고 ~~를 하라.
    • ifPresent(Consumer)

  • Optional에 값이 있으면 가져오고 없는 경우에 ~~를 리턴 하라.
    • orElse(T)

  • Optional에 값이 있으면 가져오고 없는 경우에 ~~를 하라.
    • orElseGet(Supplier)

  • Optional에 값이 있으면 가져오고 없는 경우 에러를 던져라.
    • orElseThrow()

  • Optional에 들어있는 값 걸러내기
    • Optional filter(Predicate)

  • Optional에 들어있는 값 변환
    • Optional map(Function)
    • Optional flatMap(Function)
      • Optional 안에 들어있는 인스턴스가 Optional인 경우에 사용하면 편리하다.



예제


public static void main(String[] args) {

        List<OnlineClass> springClasses = new ArrayList<>();
        springClasses.add(new OnlineClass(1, "spring boot", true));
        springClasses.add(new OnlineClass(2, "spring data jpa", true));
        springClasses.add(new OnlineClass(3, "spring mvc", false));
        springClasses.add(new OnlineClass(4, "spring core", false));
        springClasses.add(new OnlineClass(5, "rest api development", false));

        OnlineClass spring_boot = new OnlineClass(1, "optional boot", true);
        Optional<Progress> progress = spring_boot.getProgress();
        progress.ifPresent((p) -> System.out.println(p.getStudyDuration()));

        Optional.of(10);
        OptionalInt.of(10);
        
    
        //Optional 활용
        Optional<OnlineClass> optional = springClasses.stream()
                .filter(oc -> oc.getTitle().startsWith("spring"))
                .findFirst();

        boolean present = optional.isPresent();
        boolean empty = optional.isEmpty();
        System.out.println(!present);
        System.out.println(empty);
      
        optional.ifPresent(oc -> System.out.println(oc.getTitle()));
      
        System.out.println(onlineClass.getTitle());
    

        Optional<OnlineClass> optional2 = springClasses.stream()
                .filter(oc -> oc.getTitle().startsWith("jpa"))
                .findFirst();
        OnlineClass onlineClass2 = optional2.orElseThrow(IllegalStateException::new);
        System.out.println(onlineClass2.getTitle());


        Optional<OnlineClass> onlineClass1 = optional.filter(OnlineClass::isClosed);
        System.out.println(onlineClass1.isEmpty());
        System.out.println(onlineClass1.isPresent());


        Optional<Integer> integer = optional.map(OnlineClass::getId);
        System.out.println(integer.isPresent());

       
        Optional<Optional<Progress>> progress1 = optional.map(OnlineClass::getProgress);
        Optional<Progress> progress2 = progress1.orElseThrow();
    

        Optional<Progress> progress4 = optional.flatMap(OnlineClass::getProgress);
    }
profile
습관이 전부다.

0개의 댓글