【Java8】Optional你真的会用吗?用好Optional这些骚操作,让你

【Java8】Optional 详解
1、 Optional介绍
传统的写代码方式经常会遇到NullPointerException,这就需要我们在代码中经常判空。而判空的写法又会显得很累赘,这里就可以用到Optional来简化代码。
① Optional是在java.util包下的一个用于代替null的一个工具类;
② Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
③ Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。Optional 类的引入很好的解决空指针异常。
2、构建Optional对象
① 创建一个空的 Optional 实例
Optional<String> emptyOptional = Optional.empty();
② 创建一个 Optional 实例,当 t为null时,抛出NullPointerException异常
Optional<String> notNullOptional = Optional.of("aaa");
③ 创建一个 Optional 实例,但当 t为null时不会抛出异常,而是返回一个空的实例
Optional<String> notNullOptional = Optional.ofNullable("aaa");
3、 获取Optional中的值
获取optional实例中的对象,当optional 容器为空时报错,抛出NoSuchElementException,获取前可以使用ifPresent进行判断。
Optional<String> optional = Optional.of("Hello optional"); System.out.println("optional get is :"+optional.get()); optional.ifPresent(System.out::println);
4、判断方法
Optional<String> optional = Optional.of("aaa");
① 判断optional是否为空,如果空则返回false,否则返回true
System.out.println(optional.isPresent());
② 如果optional不为空,则将optional中的对象传给Comsumer函数
optional.ifPresent(System.out::println);
③ 检查Optional实例是否有值,如果实例非null,就返回实例值,否则返回指定的其它值
String aa = optional.orElse("haha"); System.out.println(aa);
④ 如果optional不为空,则返回optional中的对象;如果为null,则使用Supplier函数生成默认值other
optional.orElseGet(() -> "Default Value")
orElseGet(Supplier supplier):功能与orElse一样,只不过orElseGet参数是一个对象
⑤ 如果optional不为空,则返回optional中的对象;如果为null,则抛出Supplier函数生成的异常
String bb = optional.orElseThrow(() -> new Exception("抛出异常"));
⑥ filter(Predicate p):如果有值并且满足条件,就返回该Optional,否则返回空Optional
Optional<User> result = Optional.ofNullable(user).filter(u -> u.getEmail() != null && u.getEmail().contains("@"));
⑦ 如果optional不为空,则将optional中的对象 t 映射成另外一个对象 u,并将 u 存放到一个新的optional容器中。
Optional<Integer> notNullToInteger = notNullOptional.map((value) -> 1);
5、Optional 的不正确使用案例
- 不要直接拿来做if-else的判定条件,这肯定不合理的:
Optional<User> user = ...... if (user.isPresent()) { return user.getOrders(); } else { return Collections.emptyList(); }
而且get()要配合isPresent()才安全。
- 其次,尽量不要用 Optional 拿来做成员变量,特别是 pojo 的成员变量,这很容易让读 pojo 的框架出问题。
- 再次,不要拿来做方法参数,因为很可能写成 if (user.isPresent()) {}式的代码。
- 最后,Optional 的关注点在它的 value 的后续处理身上,如果这个 value 只是一个 flag,建议直接使用if-else;如果这个 value 被用在多路返回里,也不能使用 Optional。