关于Optional

日常编码过程中,空指针异常非常常见。在jdk8以后,添加了Optional,用来解决这个问题。

Optional简单来说可以类比成操作单个对象的Stream

接下来介绍一下Optional:

创建Optional

其中第一行创建了一个空Optional,get()是从 Optional 实例中取回实际值对象的方法之一:

    public static void main(String[] args) {
        Optional<Haozi> emptyOpt = Optional.empty();
        emptyOpt.get();
    }

而如果这是这样,运行结果会报错:

看源码可以看出,empty()只是返回了一个空对象。

所以我们需要另外的方式:

of()和ofNullable(),二者的区别是如果把null作为参数传进去,of()还是会报空指针异常。

    public static void main(String[] args) {
        Optional<Haozi> emptyOpt = Optional.of(null);
//      Optional<Haozi> emptyOpt = Optional.ofNullable(null);
    }

看下of()的源码

再看下ofNullable()

通过源码可以看出,ofNullable()还是调用的empty(),所以并不是说用了ofNullable就无敌了,这个情况下再get(),还是会有问题,他只是整合了判断非空的问题。

所以在对象明确不为null的时候再用of(),不然就用ofNullable()。

获取Optional的值

从上面我们大致了解了get()

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        Optional<Haozi> optional = Optional.ofNullable(haozi);
        System.out.println(optional.get());
    }

当然,我们已经知道,如果是null一样会报错,因此我们可以先进行判断非空,Optional提供了一个api:isPresent()

接下来引申出来另一个:ifPresent(),有值就执行断言:

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        Optional<Haozi> optional = Optional.ofNullable(haozi);
        optional.ifPresent(u -> System.out.println("is true"));
    }

一直在说非空非空,如果有空值应该怎么处理?

orElse()

很简单,但要注意的是,他返回的是泛型类,并非Optional

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        Haozi result = (Haozi) Optional.ofNullable(null)
                .orElse(haozi);
        System.out.println(result);
    }

同类型的还有orElseGet()

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        Haozi result = (Haozi) Optional.ofNullable(null)
                .orElseGet(() -> haozi);
        System.out.println(result);
    }

异同点:这两个方式在前面条件是null的情况下,结果是一样的。而如果前面不为null:

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        Haozi result = (Haozi) Optional.ofNullable(haozi)
                .orElse(creatHaozi());
        System.out.println(result);
    }

    private static Haozi creatHaozi(){
        System.out.println("creating");
        return null;
    }

返回值:

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        Haozi result = (Haozi) Optional.ofNullable(haozi)
                .orElseGet(() -> creatHaozi());
        System.out.println(result);
    }

    private static Haozi creatHaozi(){
        System.out.println("creating");
        return null;
    }

返回值:

由此可见,orElse()不管前面是不是空,都会执行后面的内容。所以二者用起来还是要注意。

返回异常:

除了orElse()和orElseGet(),还提供了orElseThrow(),作用是当前面为null时抛出异常,这样我们可以自由的定义异常内容,而不仅仅是空指针

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        Haozi result = (Haozi) Optional.ofNullable(null)
                .orElseThrow(() -> new IllegalArgumentException());
        System.out.println(result);
    }

Optional其他api

Optional提供了好多api进行值的操作:

map()与flatMap()

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        String result = Optional.ofNullable(haozi)
                .map(h -> h.getName())
                .orElse("abc");
        System.out.println(result);
    }

map()比较简单,不多说了

public class Haozi {
    private String name;
    private String address;

    public Optional<String> getName() {
        return  Optional.ofNullable(name);
    }
//...
}
    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        String result = Optional.ofNullable(haozi)
                .flatMap(h -> h.getName())
                .orElse("abc");
        System.out.println(result);
    }

map()与flatMap()的异同

对比可以知道,这两个作用是一样的。区别就是:

如果返回值不是Optional类型数据的时候,用map,map会进行一次Optional包装

如果返回值是Optional类型数据的时候,用flatMap,直接返回。

filter()

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , null);
        Optional<Haozi> result = Optional.ofNullable(haozi)
                .filter(h -> h.getAddress() != null);
        System.out.println(result.get());
    }

很简单的一个过滤操作,如果通过就返回,不通过返回空Optional

Java9增强

java9新增了3中方法:or()、ifPresentOrElse() 和 stream()

or()与orElse() 和 orElseGet() 类似,它们都在对象为空的时候提供了替代情况。or() 的返回值是由 Supplier 参数产生的另一个 Optional 对象。

    public static void main(String[] args) {
        Haozi result = (Haozi) Optional.ofNullable(null)
                .or(() -> Optional.of(new Haozi("haozi","home")))
                .get();
        System.out.println(result);
    }

ifPresentOrElse()

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , null);
        Optional.ofNullable(null)
                .ifPresentOrElse(
                        h -> System.out.println("true"),
                        () -> System.out.println("false"));
    }

如果非空,执行逗号前面的,反之执行后面的。该方法在有值的时候执行某个动作,或者只是跟踪是否定义了某个值的时候非常有用。

stream()

可以把实例转换成stream流,从而使用stream的各种api

    public static void main(String[] args) {
        Haozi haozi = new Haozi("haozi" , "home");
        List<String> addressList = Optional.ofNullable(haozi)
                .stream()
                .filter(h -> h.getAddress() != null)
                .map(h -> h.getAddress())
                .collect(Collectors.toList());
        System.out.println(addressList.size());
    }

 

 

综上,关于Optional的用法就说到这里,接下来多多实践。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值