Java8新特性Optional 详解
一、概述
java.util.Optional<T>
类是一个封装了Optional
值的容器对象,Optional
值可以为null,如果值存在,调用isPresent()
方法返回true,调用get()方法可以获取值。
Optional是在java.util包下的一个用于代替null的一个工具类。
Optional 类的引入很好的解决空指针异常。
import java.util.Optional;
二、使用目的
1.避免使用null检查。
开发中,几乎都会遇到NullPointerException
异常,大都是通过if判定null值,比如:
public void addUserRole(User user) {
if (user == null) {
return;
}
String roleId = user.getRoleId();
if (roleId == null) {
return;
}
}
这种方式不方便出错后调试,因此,Java 8中引入了一个新的类Optional,用以避免使用null值引发的种种问题。
三、构建Optional
Optional类提供类三个方法用于实例化一个Optional对象,它们分别为empty()、of()、ofNullable()。
(1)empty()方法:empty()方法用于创建一个没有值的Optional对象:
Optional<String> emptyOpt = Optional.empty();
(2)of()方法:of()方法使用一个非空的值创建Optional对象。
String str = "my";
Optional<String> notNullOpt = Optional.of(str);
(3)ofNullable()方法:ofNullable()方法接收一个可以为null的值。
Optional<String> nullableOpt = Optional.ofNullable(str);
如果str的值为null,得到的nullableOpt是一个没有值的Optional对象。
四、Optional中相关方法
1.isPresent(): 持有非空值,返回true;否则false;
Optional optional = Optional.ofNullable(null);
Optional optional1 = Optional.of("");
Optional optional2 = Optional.empty();
System.out.println(optional.isPresent());
System.out.println(optional1.isPresent());
System.out.println(optional2.isPresent());
结果:
分别为 false、true、false。
2.ifPresent(): 如果 Optional 中有值,则对该值调用consumer.accept,否则什么也不做。
3.orElse: 参数是一个值,如果 Optional 中有值则将其返回,否则返回 orElse 方法传入的参数。
Optional 中有值:
Optional optional = Optional.ofNullable("admin");
System.out.println(optional.orElse("error"));
结果:
admin
Optional 中没有值:
//Optional 中有没有值
Optional optional = Optional.ofNullable(null);
System.out.println(optional.orElse("error"));
结果:
error
注:Optional 只有null时表示为空值,其他任何情况都不表示空值,如空字符串。
4.orElseGet: 传入的参数为一个 Supplier 接口的实现。
5.orElseThrow: 没有值的时候会抛出异常,抛出的异常由传入的 exceptionSupplier 提供。
如下:
return Optional.ofNullable(user.getUserId())
.orElseThrow(() -> new BizException(“异常”));
6.map: 为空返回 Optional.empty;否则返回一个新的 Optional:函数 mapper 在以 value 作为输入时的输出值;可以多次使用map操作。
Optional<String> nickname = Optional.ofNullable(user.getUserId())
.map(user -> user.getNickname())
.map(name -> name.replace(' ', ''));
System.out.println("nickname is: " + nickname.orElse("unknown"));
7.flatMap: map 方法参数中的函数 mapper 输出的是值,然后 map 方法会使用 Optional.ofNullable 将其包装为 Optional;而 flatMap 要求参数中的函数 mapper 输出的就是 Optional。
Optional<String> nickname = Optional.ofNullable(user.getUserId())
.flatMap(user -> Optional.of(user.getNickname()))
.flatMap(name -> Optional.of(name.toLowerCase()));
System.out.println("nickname is: " + nickname.orElse("unknown"));
8.filter: 接受一个 Predicate 来对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.empty。
Optional<User> optional = Optional.ofNullable(user).filter(u -> u.getUserId == userId).orElse(null);