Optional
类 是jdk 1.8
后新添加的特性,阿里巴巴的代码规范也明确说明了使用 Optional 来防止NPE。
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。
它拥有的方法:
属性
1 | // @since 1.8 |
value 属性就是存储数据的地方。如果为null,表示没有值的存在,取值的时候如果没有默认值,会抛出空指针。
方法
构造方法
它拥有两个构造方法:
1 | /** |
- 第一个构造一个空的Optional;
- 第二个构造一个值为value的Optional,值为null会抛出NPE;
of
为非null的值创建一个Optional。
of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException。
源码:
1 | public static <T> Optional<T> of(T value) { |
可以看出它最后调用的是第二个有参的构造函数,所以它传入的参数也为null会抛出空指针。
1 | Optional<String> spring = Optional.of("SPRING"); |
最后个创建Optional实例会抛出空指针异常。
ofNullable
1 | /** |
为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。
相比较of 方法,能够接受 null 参数。
isPresent
判断值是否存在。值不为null,返回true。
1 | public boolean isPresent() { |
get
取出存在Optional 中的值,为Null 抛出NoSuchElementException
异常
1 | public T get() { |
ifPresent
1 | /** |
对传入的值使用Consumer
接口的accept方法进行处理,
1 | /** |
实际上就是可以使用函数式编程了,使用lambda表达式方法了,前提是
1 | spring.ifPresent(a -> System.out.println(a.indexOf("I"))); |
结果为 3
。
orElse
如果有值则将其返回,否则返回指定的其它值。
1 | System.out.printf("有值的Optional: %s,没值的Optional:%s%n", |
打印结果:
1 | 有值的Optional: SPRING,没值的Optional:summer |
orElseGet
orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值,由于参数是接口形式,直接使用lambda表达式,更方便。
能接收函数式返回处理的数据。
1 | System.out.printf("有值的Optional: %s,没值的Optional:%s%n", |
输出:
1 | 有值的Optional: SPRING,没值的Optional:summer |
orElseThrow
如果有值则将其返回,否则抛出supplier接口创建的异常。
在上面的 orElseGet 方法中,传入的是Supplier接口的实现,在orElseThrow中传入一个Throwable ,如果值不存在来抛出传入的指定类型异常,源码:
1 | public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X { |
使用方法:
1 | //orElseThrow |
结果符合预期错误抛出结果:
1 | 有值的Optional: SPRING,没值的Optional:summer |
map
如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。
map就是stream中的方法一样的,是用来操作的,用来对Optional实例的值执行一系列操作,所以我们可以灵活的使用Function包的方法和lamdba表达式。
1 | //map |
输出结果:
1 | 转换过后的值:spring |
可以看出转换成小写的了。
flatMap
如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。flatMap与map(Funtion)方法类似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装。
1 | //flatMap |
输出结果:
1 | 将上面小写的castedOptional 转换成大写:SPRING |
filter
如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional。
过滤,对于filter函数我们应该传入实现了Predicate接口的lambda表达式。
1 | /filter |
输出结果:
1 | 过滤掉长度不大于10的结果 :Default value |
学习的所有代码
1 | package com.wuwii.utils; |