Optional-API

背景

  1. Optional出现的背景:Java引用中非常容易出现空指针异常,Java8通过将Null所在的变量封装一层,内部仍然利用null来判断是否为空指针,对外屏蔽空指针使用。
  2. 源码分析Optional封装特点引用对象。
public final class Optional<T> {
    /**
     * Common instance for {@code empty()}.
     */
    private static final Optional<?> EMPTY = new Optional<>();

    /**
     * If non-null, the value; if null, indicates no value is present
     */
    private final T value;
}

OptinalAPI

  1. empty:对Null引用的封装,调用orElse(),如果为null就返回Other对象
 public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

    public T orElse(T other) {
        return value != null ? value : other;
    }
    @Test
    /**
     * 封装null
     */
    public void testEmpty(){
        Optional<String> empty = Optional.empty();
        Assert.assertEquals("",empty.orElse(""));
    }
  1. of与ofNullable:工厂方法创建对象
    /**
    *ofNullabe:创建可以为Null引用的Optional对象
    */
public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
   /**
    *of:不能够为Null引用的Optional对象
    */ 
public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
 private Optional(T value) {
        this.value = Objects.requireNonNull(value);
}

3.map:封装对象调用API

    /**
     * 对封装对象调用API
     */
    public void testInvokeApi(){
        Optional<String> message = Optional.of("hello");
        Optional<Integer> integer = message.map(item -> {
            return item.length();
        });
    }
        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));
        }
    }
  • map方法如果当前Optional有值则返回Empty对象,否则调用方法处理Value并且生成对应Optional
  1. flatMap:压缩Optional<Optional>为Optinal对象
 /**
     * 使用flatMap链接Optional对象
     */
    public void testFlagMap(){
        Optional<String> message = Optional.of("hello");
        Optional<Boolean> aBoolean = message.map(s -> s.length()).map(number -> number > 5);
        Optional<Person> personOpt = Optional.of(new Person());
        //编译错误
        //personOpt.map(p->p.car).map(car->car.cardId)
        //map->Optional<Optional<String>>
        //flatMap->Optional<String>
        Optional<String> s = personOpt.flatMap(p -> p.car).flatMap(car -> car.cardId);
    }
    class Car {
        Optional<String> cardId;
    }
    class Person{
        Optional<Car> car;
    }
    /***
    * 源码
    */
    public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }
    
  • 源码可以看出flatMap接受的参数必须返回一个Optional<>类型的值,并且源码为直接调用该方法生成对象,而非map的new Optional(U)
  • 源码可以看出无论map与flatMap都是在对象为Null的时候生成Empty变量
  1. filter:过滤特定的值,为null就不过滤
 @Test
    public void testFilter(){
        Optional<String> message = Optional.of("hello");
        System.out.println(message.filter(s -> s.length() > 3).orElse("no content"));
    }
//源码:
public Optional<T> filter(Predicate<? super T> predicate) {
        Objects.requireNonNull(predicate);
        if (!isPresent())
            return this;
        else
            return predicate.test(value) ? this : empty();
    }
  • 只有当前Optional为非Empty且满足条件则返回该Optional对象否则返回Empty对象
    6.获取值:get/orElse/orElseGet/orElseThrow
        public T get() {
        if (value == null) {
            throw new NoSuchElementException("No value present");
        }
        return value;
    }

    public T orElse(T other) {
        return value != null ? value : other;
    }
    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }
    
    public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        if (value != null) {
            return value;
        } else {
            throw exceptionSupplier.get();
        }
    }
  • get:如果封装值为Null则抛出异常,否则返回封装值
  • orELse:如果封装值为Null则返回Other值
  • orElseGet:如果封装值为Null则利用other调用生成结果值
  • orELseThrow:如果封装值为Null则利用异常生成器生成结果异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值