美文网首页
java optional

java optional

作者: flyjar | 来源:发表于2023-04-05 10:42 被阅读0次
    package xin.altitude.java.util;
    
    import java.util.NoSuchElementException;
    import java.util.Objects;
    import java.util.function.Consumer;
    import java.util.function.Function;
    import java.util.function.Predicate;
    import java.util.function.Supplier;
    
    
    /**
     * <p>处理空指针包装器</p>
     *
     * @author explore
     */
    public final class Optional<T> {
        
        private static final Optional<?> EMPTY = new Optional<>();
        
        
        private final T value;
        
        
        private Optional() {
            this.value = null;
        }
        
        
        private Optional(T value) {
            this.value = java.util.Objects.requireNonNull(value);
        }
        
        public static <T> Optional<T> empty() {
            @SuppressWarnings("unchecked")
            Optional<T> t = (Optional<T>) EMPTY;
            return t;
        }
        
        /**
         * <p>创建{@code Optional}包装器实例</p>
         * <p>使用此方法需要严格保证参数<code>value</code>不能为<code>null</code>,否则请使用另一个方法{@link #ofNullable(Object)}</p>
         *
         * @param value 普通的对象实例
         * @param <T>   对象的类型
         * @return {@code Optional}包装器实例
         */
        public static <T> Optional<T> of(T value) {
            return new Optional<>(value);
        }
        
        
        /**
         * <p>创建{@code Optional}包装器实例</p>
         * <p>不确定参数<code>value</code>是否为<code>null</code>,则使用本方法,大多数情况下如此</p>
         *
         * @param value 普通的对象实例
         * @param <T>   对象的类型
         * @return {@code Optional}包装器实例
         */
        public static <T> Optional<T> ofNullable(T value) {
            return value == null ? empty() : of(value);
        }
        
        
        /**
         * <p>创建{@code Optional}包装器实例中取出真实的对象实例</p>
         * <p>调用本方法之前 需要先调用{@link #isPresent()}方法判断真实对象是否为<code>null</code>,如果存在再调用本方法</p>
         * <pre>
         *     if(opt.isPresent()){
         *         T t = opt.get();
         *     }
         * </pre>
         * <p>如果不判断直接调用本方法 很可能抛出{@link NoSuchElementException}</p>
         *
         * @return 真实对象实例
         */
        public T get() {
            if (value == null) {
                throw new NoSuchElementException("No value present");
            }
            return value;
        }
        
        
        /**
         * 判断{@code Optional}包装器实例中真实对象是否存在
         */
        public boolean isPresent() {
            return value != null;
        }
        
        
        /**
         * <p>如果包包裹的对象存在 则执行回调方法</p>
         * <p>高频使用方法</p>
         *
         * @param consumer
         */
        public void ifPresent(Consumer<? super T> consumer) {
            if (value != null) {
                consumer.accept(value);
            }
        }
        
        /**
         * <p>本方法使用不多</p>
         */
        public Optional<T> filter(Predicate<? super T> predicate) {
            java.util.Objects.requireNonNull(predicate);
            if (!isPresent()) {
                return this;
            } else {
                return predicate.test(value) ? this : empty();
            }
        }
        
        
        /**
         * 将被包裹的对象从{@code T}实例转化成{@code U}实例
         * <pre>
         *     Long userId = Optional.ofNullable(user).map(User::getUserId).orElse(null);
         * </pre>
         * <p>传统方式只能按照如下方式编码</p>
         * <pre>
         *     if(user != null){
         *         Long userId = user.getUserId();
         *     }
         * </pre>
         * <p>高频使用方法</p>
         *
         * @param mapper 转换规则 Lambda或者方法引用表示
         * @param <U>    转换后的对象类型
         * @return {@code U}类型的新的包装器实例
         */
        public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
            java.util.Objects.requireNonNull(mapper);
            if (!isPresent()) {
                return empty();
            } else {
                return Optional.ofNullable(mapper.apply(value));
            }
        }
        
        
        public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
            java.util.Objects.requireNonNull(mapper);
            if (!isPresent()) {
                return empty();
            } else {
                return java.util.Objects.requireNonNull(mapper.apply(value));
            }
        }
        
        /**
         * <p>从{@code Optional}包装器实例尝试获取值 如果不存在 则返回参数<code>other</code>指定的值</p>
         * <p>使用方法参考{@link #map(Function)}参考实例</p>
         * <p>高频使用方法</p>
         */
        public T orElse(T other) {
            return value != null ? value : other;
        }
        
        /**
         * <p>使用场景与{@link #orElse(Object)}类似,区别是能够通过回调方法动态指定<i>默认值</i></p>
         * <p>高频使用方法</p>
         */
        public T orElseGet(Supplier<? extends T> other) {
            return value != null ? value : other.get();
        }
        
        /**
         * <p>使用场景与{@link #orElse(Object)}类似,区别是如果真实对象不存在,则抛出指定回调异常</p>
         */
        public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
            if (value != null) {
                return value;
            } else {
                throw exceptionSupplier.get();
            }
        }
        
        
        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            
            if (!(obj instanceof Optional)) {
                return false;
            }
            
            Optional<?> other = (Optional<?>) obj;
            return java.util.Objects.equals(value, other.value);
        }
        
        
        @Override
        public int hashCode() {
            return Objects.hashCode(value);
        }
        
        
        @Override
        public String toString() {
            return value != null
                    ? String.format("Optional[%s]", value)
                    : "Optional.empty";
        }
    }
    
    

    常见用法


    image.png

    相关文章

      网友评论

          本文标题:java optional

          本文链接:https://www.haomeiwen.com/subject/uwdnsktx.html