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是后端开发人员的最基本素养,你说呢?好了,今天的内容就到这里吧,新的一周开始了,大家都要元气慢慢哦

  • 相关阅读:
    Jedis客户端以及redis中的pipeline批量操作
    Redis5.x两种持久化方式以及主从复制配置
    博客园原创文章防剽窃、反爬虫指南(持续更新.....)
    【金主打赏榜】
    Swift LeetCode 目录 | Catalog(每周日更新......)
    [Swift]SkeletonView:在UITableView中使用骨架屏
    【Xcode】加快Xcode编译调试速度
    【Xcode】ITMS-90809:查找UIWebView
    [Swift]PhotoKit-照片框架
    [SourceTree]remote: HTTP Basic: Access denied
  • 原文地址:https://www.cnblogs.com/caoleiCoding/p/14802922.html
Copyright © 2011-2022 走看看