美文网首页
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