1. 특징

    1. NullPointerException을 방지해주는 즉 null인 값을 참조해도 NullPointerException이 발생하지 않도록 값을 래퍼로 감싸주는 타입
    Member member = memberRepository.findById(memberId)
    																.orElseThrow(MemberNotFoundException :: new)
    																//실제로는 Optional 타입이다.
    
    1. 원하는 member를 찾기 못했을 경우 MemberNotFoundExceptiond을 발생시켜, NullPointerException을 미리 방지할수 있다.
  2. Optional 사용 방법

    1. Optional 생성 Static 메소드
      1. empty()

        1. 특징

          1. 비어있는 Optional 객체를 생성
          2. 리턴값 : Optional<T>
          3. 예제
          Optional<String> empty = Optional.empty();
          //아웃풋
          System.out.println(empty.isEmpty()) //true
          
          
      2. of(T value)

        1. 특징
          1. 전달된 값으로 새로운 Optional 객체를 생성

          2. 리턴값: Optional<T>

          3. 예제

            //Optional 메소드
            Optional <String> opt = Optional.of("Hello");
            
            //아웃풋
            System.out.println(opt.get()); // Hello
            
      3. OfNullable(T value)

        1. 특징
          1. 비어있을 수도 있고, 아닐 수도 있는 Optional 객체를 생성

          2. 반환값 : Optional<T>

          3. 예시

            // Optional 메소드
            String imNull = null;
            Optional<String> opt = Optional.ofNullable(imNull);
            Optional<String> opt1 = Optional.ofNullable("Hello");
            
            //아웃풋
            System.out.println(opt.isEmpty()); //true
            System.out.println(opt1.isEmpty()); //false
            
  3. equals(Object obj)

    1. 특징

      1. Optional 객체의 값을 비교
      2. 리턴값: boolean
      //인풋
      Optional<String> opt1 =Optional.of("Hello");
      Optional<String> opt2 = Optional.of("Hello");
      Optional<String> opt3 = Optional.of("World");
      
      // Optional 메소드
      boolean isEqual1 = opt1.equals(opt2);
      boolean isEqual2 = opt1.equals(opt3);
      
      //아웃풋
      System.out.println(isEqual1); //true
      System.out.println(isEqual2); //false
      
  4. filter()

    1. filter(Predicate <? Super T> predicate)

    2. 특징

      1. Optional 객체의 값을 조건에 따라 필터링
      2. 리턴값: Optional
      Optional<Integer> opt1 = Optional.of(10);
      Optional<Integer> opt2 = Optional.of(1);
      
      // Optional 메소드
      Optional <Integer> filter1 = opt1.filter(num -> num < 5);
      Optional <Integer> filter2 = opt2.filter(num -> num < 5);
      
      //아웃풋
      System.out.println(filter1.isEmpty()); //true
      System.out.println(filter2.isEmpty()); //false
      
  5. map()

    1. .map(Function<? Super T, ? Extends U> mapper)
    2. 특징
      1. Optional 객체 내부의 값을 변환하여 결과를 새로운 Optional 객체로 반환

      2. 리턴값 : Optional<U>

      3. 예시

        //인풋
        Optional<String> optional = Optional.of("hello");
        
        //Optional 메소드
        Optional<Integer> result = Optional.map(s -> s.length());
        
        // 아웃풋
        SYstem.out.println(result.get()); //5
        
  6. flatMap()

    1. .flatMap(Function <? Super T, ? Extends Optional <? Extends U>> mapper)

    2. 특징

      1. 중첩된 Optional
      2. 리턴값: Optional<U>
    3. 예시

      Optional <String> opt = Optional.of("Hello");
      
      //Optional 메소드
      Optional<String> flatMappedOpt = opt.flatmap(str -> Optional.of(str.toUpperCase()));
      //아웃풋
      System.out.println(flatMappedOpt.get()); //HELLO
      
  7. get()

    1. .get()
    2. 특징
      1. Optional 객체의 값을 가져옴(값이 존재하지 않는 경우, NoSuchElementException이 발생)
      2. 리턴값: T
    3. 예시
    Optional<String> opt1 = Optional.ofNullable("Hello");
    Optional<String> opt2 = Optional.ofNullable(null);
    
    // 아웃풋
    System.out.println(opt1.get()); //Hello
    System.out.println(opt2.get()); //NoSuchElementException
    
  8. isEmpty()

    1. isEmpty()
    2. 특징
      1. Optional 객체가 비어있느지 확인
      2. 리턴 값: boolean
    3. 예시
    //인풋
    Optional<String> opt1 = Optional.ofNullable("Hello");
    Optional<String> opt2 = Optional.ofNullable(null);
    
    //아웃풋
    System.out.println(opt1.isEmpty()); //false
    System.out.println(opt2.isEmpty()); //true
    
  9. isPresent()

    1. isPresent()
    2. 특징
      1. Optional 객체가 있는지 확인
      2. 리턴값 : boolean
    3. 예제
    // 인풋
    Optional<String> opt1 = Optional.ofNullable("Hello");
    Optional<String> opt2 = Optional.ofNullable(null);
    
    // 아웃풋
    System.out.println(opt1.isPresent()); //true
    System.out.println(opt2.isPresent()); //false
    
  10. ifPresent()

    1. ifPresent(Consumer <? Super T> action)
    2. 특징
      1. Optional객체가 있다면 내부 연산을 실행
      2. 리턴값 void
    3. 예시
    // 인풋
    Optional<String> opt1 = Optional.ofNullable("Hello");
    Optional<String> opt2 = Optional.ofNullable(null);
    
    //아웃풋
    opt1.ifPresent(str -> System.out.println(str)); //Hello
    opt2.ifPresent(str -> System.out.println(str));
    
  11. ifPresentOrElse()

    1. ifPresentOrElse(Consumer<? Super T> action, Runnable emptyAction)

    2. 특징

      1. Optional 객체가 있다면 내부 연산을 실행, 없다면 또 다른 내부 연산을 실행
      2. 리턴값: void
    3. 예제

      // 인풋
      Optional<String> opt1 = Optional.ofNullable("Hello");
      Optional<String> opt2 = Optional.ofNullable(null);
      
      //아웃풋
      opt1.ifPresentOrElse(str -> System.out.println(str),() -> System.out.println("null")); // Hello
      
      opt2.ifPresentOrElse(str -> System.out.println(str),
      												() -> System.out.println("null")); //null
      
  12. or()

    1. .or(Supplier<? Extends Optional<? extends T>> supplier)
    2. 특징
    3. 예제
    // 인풋
    Optional<String> optional1= Optional.empty();
    Optional<String> optional2 = Optional.of("Hello");
    
    // Optional 메소드 사용
    Optional<String> result1 = optional1.or(() -> Optional.of("World"));
    Optional<String> result2 = optional2.or(()-> Optional.of("World"));
    
    // 아웃풋
    System.out.println (result1.get()); // World
    System.out.println(result2.get()); // Hello
    
  13. orElse(0