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