java中的optional

简介

一个避免NPE的神器

String isocode = user.getAddress().getCountry().getIsocode().toUpperCase();

这行代码一般而言,你只敢向下面这么写

if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        Country country = address.getCountry();
        if (country != null) {
            String isocode = country.getIsocode();
            if (isocode != null) {
                isocode = isocode.toUpperCase();
            }
        }
    }
}

但是使用Optional进行简化后

String result = Optional.ofNullable(user)
  .flatMap(User::getAddress)//这个函数输出是一个Optianal的对象
  .flatMap(Address::getCountry)//这个函数输出的也是一个Optioanl对象。
  .map(Country::getIsocode)
  .orElse("default");

原理

public final class Optional<T> {


	//如果是null,返回一个Optional<输入类型>的空实例。否则输出Optional<输入类型>的输入的包装Optionl对象。
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }

    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }

    private static final Optional<?> EMPTY = new Optional<>();


    //function范型中第一个是入参,第二个是返回值。
    //flatMap和map接受的fuction,入参数必须是当前Optional类范型T的父类。这是很自然的。
    //区别在于,flatMap要求函数输出的Optional对象,必须是Optioanl的包装,而map要求是U的子类。
    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));
        }
    }
    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));
        }
    }

实际应用

一个最简单的例子如下

    public static void main(String[] args) throws Exception{

        A a = new A();
        String x = Optional.ofNullable(a).map(A::getB).map(B::getC).map(C::getD).orElse("default");
        System.out.println(x);
    }

    @Getter
    @Setter
    static class A{
        B b;
    }

    @Getter
    @Setter
    static class B{
        C c;
    }

    @Getter
    @Setter
    static class C{
        String d;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值