자바 에서 optional 사용 에 대한 상세 한 분석

18121 단어 자바optional쓰다
optional 사용 설명
1.옵션 소개
  •  optional 클래스 는 null 을 위 한 용기 대상 입 니 다.값 이 존재 하면 isPresent()방법 은 true 를 되 돌려 주 고 get()방법 을 호출 하면 대상 을 되 돌려 줍 니 다.
  • Optional 은 용기 입 니 다.형식 T 의 값 을 저장 하거나 null 만 저장 할 수 있 습 니 다.optional 은 빈 값 검 사 를 하지 않 아 도 되 는 유용 한 방법 을 많이 제공 합 니 다.
  • Optional 류 의 도입 은 빈 포인터 이상 을 잘 해결 합 니 다.
  • 2.구축 옵션
    옵션 대상 구축 하기;방법:empty(),of(),of Nullable()
    
     //          Optional ,    null ,       Optional 。
            //  : C      null 
            //    :<T> C    
            //   :  Optional           null ,     Optional
            Optional.ofNullable("");
    
            //    Optional      null 。
            //  :value C     ,    null
            //    :<T> C    
            //   :    Optional
            Optional.of("");
    
            //      Optional  。  Optional   。
            //    :<T> C        
            //   :    Optional
            //api  :          ,     == Optional.empty()                    。
            //           。
            //     isPresent()
            Optional.empty();
    
    3.optional API 및 소스 코드 주석
    
    package java.util;
    
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.function.Predicate;
    import java.util.function.Supplier;
    import java.util.stream.Stream;
    
    /**
                 null      。      , isPresent()  true 。         ,        ,  isPresent()  false 。
                       ,  orElse() (      ,      ) ifPresent() (     ,     )。
             ;  Optional            (      ( == ),        )            ,     
     */
    public final class Optional<T> {
        /**
         * empty()    
         */
        private static final Optional<?> EMPTY = new Optional<>();
    
        /**
         *      ,    ;   false。    null,         
         */
        private final T value;
    
        /**
                   。
            impl  :
              ,  VM         EMPTY 
         */
        private Optional() {
            this.value = null;
        }
    
        /**
                  Optional  。  Optional   。
                :<T> C        
               :    Optional
            api  :
                      ,     == Optional.empty()                    。           。     isPresent() 
         */
        public static<T> Optional<T> empty() {
            @SuppressWarnings("unchecked")
            Optional<T> t = (Optional<T>) EMPTY;
            return t;
        }
    
        /**
                        。
              : C     null 
              :NullPointerException    null
         */
        private Optional(T value) {
            this.value = Objects.requireNonNull(value);
        }
    
        /**
                Optional      null 。
              :value C     ,    null
                :<T> C    
               :    Optiona
         */
        public static <T> Optional<T> of(T value) {
            return new Optional<>(value);
        }
    
        /**
                      Optional ,    null ,       Optional 。
              : C      null 
                :<T> C    
               :  Optional           null ,     Optional
         */
        public static <T> Optional<T> ofNullable(T value) {
            return value == null ? empty() : of(value);
        }
    
        /**
                 ,     ,    NoSuchElementException 。
               : Optional    null 
              :NoSuchElementException        
            api  :           orElseThrow() 。
         */
        public T get() {
            if (value == null) {
                throw new NoSuchElementException("No value present");
            }
            return value;
        }
    
        /**
                 ,   true ,    false 。
    
               :     ,  true ,   false
         */
        public boolean isPresent() {
            return value != null;
        }
    
        /**
                  ,   true ,    false 。
    
               :      ,  true ,   false
         */
        public boolean isEmpty() {
            return value == null;
        }
    
        /**
                 ,            ,         。
              :  C      (     )
         */
        public void ifPresent(Consumer<? super T> action) {
            if (value != null) {
                action.accept(value);
            }
        }
    
        /**
                 ,            ,             。
              :  C      (     )emptyAction C          (        )
              :NullPointerException               null ,                    null 
         	@since 9
         */
        public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) {
            if (value != null) {
                action.accept(value);
            } else {
                emptyAction.run();
            }
        }
    
        /**
                   ,            ,        Optional ,        Optional 。
    
              :  C       (    )
               :  Optional     Optional ,                   ,     Optional
              :NullPointerException     null
         */
        public Optional<T> filter(Predicate<? super T> predicate) {
            Objects.requireNonNull(predicate);
            if (!isPresent()) {
                return this;
            } else {
                return predicate.test(value) ? this : empty();
            }
        }
    
        /**
                 ,     Optional  (  by ofNullable ),               ,        Optional 。
                    null  ,        Optional 
         */
        public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
            Objects.requireNonNull(mapper);
            if (!isPresent()) {
                return empty();
            } else {
                return Optional.ofNullable(mapper.apply(value));
            }
        }
    
        /**
                    ,      Optional -bearing            ,        Optional 。
                  map(Function) ,             Optional  ,       , flatMap         Optional 。
    
              :mapper C         (    )
                :<U> C       Optional    
               :     Optional         Optional ,       ,     Optional
              :NullPointerException       null   null  
    
         */
        public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
            Objects.requireNonNull(mapper);
            if (!isPresent()) {
                return empty();
            } else {
                @SuppressWarnings("unchecked")
                Optional<U> r = (Optional<U>) mapper.apply(value);
                return Objects.requireNonNull(r);
            }
        }
    
        /**
                  ,    Optional    ,       Optional        。
    
              :   C      Optional     
               :    Optional     Optional ,       ,  Optional        。
              :NullPointerException        null   null  
         * @since 9
         */
        public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
            Objects.requireNonNull(supplier);
            if (isPresent()) {
                return this;
            } else {
                @SuppressWarnings("unchecked")
                Optional<T> r = (Optional<T>) supplier.get();
                return Objects.requireNonNull(r);
            }
        }
    
        /**
                 ,           Stream ,     Stream 。
    
               :  Stream    
         * @since 9
         */
        public Stream<T> stream() {
            if (!isPresent()) {
                return Stream.empty();
            } else {
                return Stream.of(value);
            }
        }
    
        /**
                 ,     ,    other 。
    
              :  C     (        )。    null 。
               : (    ),  other
         */
        public T orElse(T other) {
            return value != null ? value : other;
        }
    
        /**
                 ,     ,              。
    
              :   C            
               : (    ),           
         */
        public T orElseGet(Supplier<? extends T> supplier) {
            return value != null ? value : supplier.get();
        }
    
        /**
         * If a value is present, returns the value, otherwise throws
         * {@code NoSuchElementException}.
         *
         * @return the non-{@code null} value described by this {@code Optional}
         * @throws NoSuchElementException if no value is present
         * @since 10
         */
        public T orElseThrow() {
            if (value == null) {
                throw new NoSuchElementException("No value present");
            }
            return value;
        }
    
        /**
                 ,     ,                。
    
              :exceptionSupplier C             
                :<X> C       
               : (    )
              :X C        NullPointerException                 null
            api  :                          
         */
        public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
            if (value != null) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }
    }
    
    
    4.테스트 사용
    4.1 구축
    
    //          Optional ,    null ,       Optional 。
    //  : C      null 
    //    :<T> C    
    //   :  Optional           null ,     Optional
    Optional s1 = Optional.ofNullable(null);
    
    //     value    null optional  ,  of()    null       ;
    Optional<MyUser> s2 = Optional.of(new MyUser("  2","123456"));
    
    //     value   null optional  ;
    Optional<MyUser> s3 = Optional.ofNullable(null);
    
    System.out.println(s1);
    System.out.println(s2);
    System.out.println(s3);
    
    /*   
     * Optional.empty
     * Optional[MyUser{id='  2', username='123456'}]
     * Optional.empty
     **/
    
    4.2 판단 류
    
     Optional<MyUser> myUser1 = Optional.empty();
            Optional<MyUser> myUser2 = Optional.of(new MyUser("  ", "123456"));
    
            // filter    lambda,lambda    boolean;true:      ,false:      optional;
            Optional<MyUser> myUser3 = myUser2.filter(user -> "     ".equals(user.getUsername()));
    
            // isPresent    value   null;     get  ,      isPresent,      value null,    get    ;
            if (myUser1.isPresent()) {
                MyUser value = myUser1.get();
                System.out.println("optional value:" + value);
            } else {
                System.out.println("optional value==null");
            }
            // ifPresent    lambda, value!=null ,       ;  value==null ,    ;
            myUser2.ifPresent(value -> System.out.println("optional value:" + value));
    
    
            System.out.println(myUser3);
    
            //     :
            //optional value==null
            //optional value:MyUser{id='  ', username='123456'}
            //Optional.empty
    
    4.3,획득 클래스(상용)
    
      Optional<MyUser> userInfoEmptyOpt = Optional.empty();
            Optional<MyUser> userInfoOpt = Optional.of(new MyUser("  ","123456"));
    
            
            // 1、    ,    value==null,  NoSuchElementException  
            MyUser userInfo1 = userInfoOpt.get();
            
            // 2、orElse      UserInfo          ;
            //     value!=null ,  value ; value==null ,         ;
            MyUser userInfo2 = userInfoEmptyOpt.orElse(new MyUser("  1","123456"));
            
            // 3、orElseGet orElse    orElseGet      lambda   ;
            //  value!=null ,  value ;
            //  value==null ,   lambda          ;
            MyUser userInfo3 = userInfoEmptyOpt.orElseGet(() -> new MyUser("  2","123456"));
            
            // 4、orElseThrow      lambda   ,lambda    Exception; value!=null ,  value ; value==null ,     ;
            MyUser userInfo4 = userInfoOpt.orElseThrow(NullPointerException::new);
    
            System.out.println(userInfo1);
            System.out.println(userInfo2);
            System.out.println(userInfo3);
            System.out.println(userInfo4);
    
            //     :
            // UserInfo(username=  , password=123456)
            // UserInfo(username=  1, password=123456)
            // UserInfo(username=  2, password=123456)
            // UserInfo(username=  , password=123456)
    
    4.4 전환 류
    
     Optional<MyUser> userInfoOpt = Optional.of(new MyUser("  ","123456"));
    
            //   value    UserInfo,  map   Optional<String>
            Optional<String> username = userInfoOpt.map(MyUser::getId);
    
            //  map       Optional ,  map      Optional<Optional<String>>      ; flatMap           ;
            Optional<Optional<String>> unFlatMap = userInfoOpt.map(user -> Optional.of(user.getId()));
            Optional<String> flatMap = userInfoOpt.flatMap(user -> Optional.of(user.getId()));
    
            System.out.println(username);
            System.out.println(unFlatMap);
            System.out.println(flatMap);
    
            //     :
            // Optional[  ]
            // Optional[Optional[  ]]
            // Optional[  ]
    
    4.5,테스트 API 사용
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import lombok.ToString;
    import org.junit.Test;
    
    import java.math.BigDecimal;
    import java.util.Optional;
    
    /**
     * @version 1.0
     * @author: crush
     * @date: 2021-04-12 20:51
     */
    public class OptionalStudy {
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @ToString
        static class Employee {
            private Long id;
            private String name;
            private Boolean leader;
        }
    
        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        @ToString
        static class Leader {
            private Long employeeId;
            private BigDecimal bonus;
        }
    
        /**
         *   ID 1   ,          ,         ;
         * @throws
         */
        @Test
        public void tst() {
            Optional<Leader> leader = Optional.ofNullable(getEmployeeById(1L)
                            .filter(Employee::getLeader)
                            .map(Employee::getId)
                            .flatMap(this::getLeaderByEmployeeId)
                            .orElse(null));
            if (leader.isPresent()) {
                Optional.of(leader.map(Leader::getBonus).map(bonus -> String.format("  ID 1 leader   :%s", bonus)).orElse("  ID 1 leader     ")).ifPresent(System.out::println);
            } else {
                System.out.println("  ID 1 leader   ,           ,      ");
            }
        }
    
        private Optional<Employee> getEmployeeById(Long id) {
            //return Optional.of(new Employee(1L, "   ", Boolean.TRUE));
            return Optional.of(new Employee(1L, "   ", Boolean.FALSE));
        }
    
        private Optional<Leader> getLeaderByEmployeeId(Long employeeId) {
            //return employeeId == 1L ? Optional.of(new Leader(1L, BigDecimal.valueOf(1000000000))) : Optional.empty();
            return employeeId == 1L ? Optional.of(new Leader(1L, null)) : Optional.empty();
        }
    }
    
    평소:
    프로젝트 의 인 스 턴 스:
    
    return Optional.ofNullable(iNewsMapper.selectNewsWithNewsCategoryById(id))
            .orElseThrow(() -> new BaseException(DataSourceResponseEnum.SELECT_ERROR));
    
    ofNullable:
    주어진 값 을 설명 하 는 optional 을 되 돌려 줍 니 다.null 이 아니라면 빈 optional 을 되 돌려 줍 니 다.
    orElseThrow
    값 이 존재 하면 이 값 을 되 돌려 줍 니 다.그렇지 않 으 면 이상 제공 함수 에 의 한 이상 을 던 집 니 다.
    이전의 문법 은:
    
    if(iNewsMapper.selectNewsWithNewsCategoryById(id)==null){
        throw new BaseException(DataSourceResponseEnum.SELECT_ERROR);
    }
    else{
        return iNewsMapper.selectNewsWithNewsCategoryById(id);
    }
    
    이런 서법 은 비교적 추악 하 다.상술 한 추악 한 서법 을 피하 기 위해 추악 한 디자인 을 우아 하 게 만 들 었 다.JAVA 8 은 이러한 표기 법 을 최적화 하기 위해 옵션 클래스 를 제공 했다.
    예 2:
    
      Optional<News> news = Optional.ofNullable(iNewsMapper.selectNewsWithNewsCategoryById(id));
    
            news.ifPresent(item -> {
                item.setLastId(this.selectLastNewsId(id));
                item.setNextId(this.selectNextNewsId(id));
                taskExecutor.execute(() -> this.addReadCount(id, ip));
            });
            return news.orElseThrow(() -> new BaseException(DataSourceResponseEnum.SELECT_ERROR));
    
    블 로 거들 은 자신 이 처음으로 Optional 을 알 게 되 었 는데,이번에 프로젝트 를 볼 때 마침 만 나 서 잘 살 았 다.
    나의 건 의 는 좋아 하면 쓰 고,싫어 하면 쓰 지 않 는 다 는 것 이다.
    사용 하면 좀 더 우아 해 보이 지만 단점 도 뚜렷 하고 논리성 이 뚜렷 하지 않다.
    자바 의 새로운 특성 에 대한 optional 의 상세 한 해석 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 의 optional 류 에 관 한 상세 한 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기