zoukankan      html  css  js  c++  java
  • 2021.05.23 春眠不觉晓,optional知多少……

    前言

    java流式编程的大家庭里,有一个类,一直会时不时的出现在我们的世界里,当然你用或者不用,它就在那里,静静地等待着你的青睐。这个类地好处是,可以优化很多不必要地if-else,特别是真对赋值的if-else。话不多说,我们直接来看下这个神秘的类——optional.

    optional

    正如它的中文含义一样,它本身也是可选择的,你可以根据自己的需要选择不同的方法,以满足你不同的需求。我们来看下它常用的方法。

    构造方式

    optaional属于工具类范畴,所有它本身不对外提供构造方法,但是它提供了两个静态方法,你可以根据你的需要来构建基于你的对象的optional(有点绕),它本身是基于泛型构建的

    of(T value)

    直接构建optional,不管值是否为空

    ofNullable(T value)

    值为空直接返回空的optional,否则调用of(T value)

    ifPresent

    这个方法就是它的字面意思,如果存在,然后进行相应的操作

    String testStr = "optianal";
    Optional<String> testStr1 = Optional.of(testStr);
    // 如果不为空执行
    testStr1.ifPresent(System.out::println);
    

    我这里的用法就是,当testStr1存在(值不空的时候),打印其值。方法本身是支持lambda表达式,所以这里我直接用了lambda表达式。

    这个方法就可以很好的减少if-else,直接在ifPresent方法中,传入你要执行的方法即可,是不是很方便。

    isPresent()

    这个方法就是单纯判断optional的值是否为空,直接返回布尔值

    // 值不为空为true,否则为false
    if (testStr1.isPresent()) {
        System.out.println("testStr1的值为空");
    }
    

    这里的值其实就指的是我们构建的时候,传入的对象

    orElse()

    如果值不为空,则返回其值,否则将传入的值返回。这个方法也很好用,特别是在赋值的时候。

    Optional<String> s3 = Optional.of("");
    // 如果值不为空,则返回其值,否则将传入的值返回
    String s = s3.orElse("null");
    

    orElseGet()

    刚开始没发现和上面方法有啥区别,源码层面也看着大同小异。但在实际使用的时候,我发现他们还是有区别的,它需要传入Supplier<? extends T>,这个类我查了,是用来创建对象的,但是不同于传统的创建对象语法,它必须写成类名::new,这就是lambda的写法。

    也就是说,这个方法其实是传入了一个空对象

    // 如果值不为空,则返回其值,否则获取传入的值
    String s1 = s3.orElseGet(String::new);
    System.out.println("s1:" +s1);
    

    对于我这里的用法就是,如果s3的值为空的话,他会返回一个空字符串。

    orElseThrow()

    这个方法就和前面两个方法很类似了,只是它的作用是,如果值为空就抛出一个异常,这个异常也是通过Supplier<? extends T>的方式构建的,如果你需要抛出特定的异常,你可以自己定义

    // 如果值不为空,则返回其值,否则抛出一个异常
    String s2 = s3.orElseThrow(Exception::new);
    System.out.println("s2:" +s2);
    

    我发现orElse神奇的一点是,如果值为空,下面的System.out.println压根都不会执行,debug也不会走,初步推断应该是在编译层面就做了预处理

    但是看了反编译的class代码,发现又好像没出来,但是如果为空,直接就会抛出异常,这确实厉害了,后面再研究下,有知道的小伙伴可以告诉我。

    filter()

    这个方法和我们前面讲stream时的方法作用是一样的,只是这里对optional来说,如果不符合过滤条件,最后返回的是空optional,也就是说isPresentfalse

    Optional<String> sdf = s3.filter(v -> v.equals("sdf"));
    System.out.println(sdf);
    

    map()

    filter看起来类似,但是map的功能更强大,类似于一个加工厂,可以按照你的需求处理,最后返回你想要的结果:

    Optional<Boolean> test = s3.map(v -> v.equals("test"));
    Optional<String> s4 = s3.map(v -> v + "123123");
    System.out.println(s4);
    System.out.println(test);
    

    flatMap()

    这个方法和map基本上没区别,源码上也是,唯一的区别我也标出来了

    总结

    今天我们分享了一个比较好用的类——Optional,这个类我觉得在实际开发中用起来应该还是美滋滋的,至少它可以解决我们日常开发的两个问题,一个就是繁琐的if-else,看起来也确实不够友好,同时它可以让我们在日常工作中尽可能避开空指针的运行时异常,毕竟避免NPE是后端开发人员的最基本素养,你说呢?好了,今天的内容就到这里吧,新的一周开始了,大家都要元气慢慢哦

  • 相关阅读:
    Get distinct count of rows in the DataSet
    单引号双引号的html转义符
    PETS Public English Test System
    Code 39 basics (39条形码原理)
    Index was outside the bounds of the array ,LocalReport.Render
    Thread was being aborted Errors
    Reportviewer Error: ASP.NET session has expired
    ReportDataSource 值不在预期的范围内
    .NET/FCL 2.0在Serialization方面的增强
    Perl像C一样强大,像awk、sed等脚本描述语言一样方便。
  • 原文地址:https://www.cnblogs.com/caoleiCoding/p/14802922.html
Copyright © 2011-2022 走看看