1、Optional介绍
Our intention was to provide a limited mechanism for library method return types where there needed to be a clear way to represent "no result", and using null
for such was overwhelmingly likely to cause errors.
由上可见,官方的介绍为optioanl是为了避免null带来的错误,进而提供的一个可以明确表示空值的机制,如我们为了防止空指针溢出,常用的判空:
if (input != null) {
// todo
}
1.8 之后,jdk 新增了Optional来表示空结果。Optional表示空的静态方法为Optional.empty(),翻看它的实现,Optional中的 value 就是null,只不过包了一层Optional,所以说它其实是个容器。
使用Optional后的代码:
// 场景1
Input input2 = Optional.ofNullable(input).orElse(new User());
// 场景2
Optional<User> optionalUser = RemoteService.getUser();
User user = optionalUser.get().orElse(new User());
除了提示用户对象可能为null外,还在一定程度上可以减少if-else的嵌套,我们举个极端的例子。
// 用户 -> 家庭住址 -> 城市 ->邮编
String postCode = user.getAddress().getCity().getPostCode();
if (user != null) {
Address address = user.getAddress();
if (address != null) {
City city= address.getCity();
if (city != null) {
String postCode = city.getPostCode();
if (postCode != null) {
//对postCode进行操作
test(postCode);
}
}
}
}
// 使用optional
Optional<User> u = Optional.of(user);
String postCode = u.map(User::getAdress).map(Address::getCity).map(City::getPostCode).orElse("0000");
2、optional使用
(1)创建
- OPtional.empty():创建一个空实例
- Optional.of(T t):创建一个Optional实例,t为null时会抛出异常
- Optional.ofNullable(T t):创建一个可null实例,t为null时返回一个空实例
(2)从Optional获取值
- Optional.get():获取Optional中的对象,为空时会报错。
(3)判断
- isPresent():判断optional是否为空
- ifPresent(Func t):如果optinal不为空,则将optional中的对象传给Func函数
public class OptionalDemo {
public static void main(String[] args) {
User user = new User("王也", "5");
User userNull= null;
Optional<User> optional = Optional.ofNullable(user);
System.out.println(optional.isPresent());
optional.ifPresent(u -> System.out.println("optional不为null "+u));
}
}
- orElse(Func f):“否则”执行语句,一般配合判空使用,当optional中对象为空时执行f语句
User user = new User("张三");
User userNull= null;
//orElse的工作方式非常直接,如果有值则返回该值,否则返回传递给它的参数值:
User user1 = Optional.ofNullable(userNull).orElse(user);
- orElseGet(Func f):同上,如果为空,则执行Func生成默认值
User user1 = Optional.ofNullable(userNull).orElseGet(()->user );
//结果同上
两者区别:
- 当对象为空时,两者没有任何区别,均会执行Func生成默认值;
- 不为空时,orElse(f1)中的仍然会执行,而orElseGet(Func f2)则不会执行,在执行较密集的调用时,比如调用 Web 服务或数据查询,这个差异会对性能产生重大影响。
- orElseThrow():当optional中对象为空时,则抛出异常
(4)过滤
filter(Predicate p):p是一个判断语句,该接口返回测试结果为 true 的值。如果测试结果为 false,会返回一个空的 Optional。
(5)映射
参考: