文章目录
Optional 简介
使用Optional用来表示一个引用对象存在或者不存在
Optional类主要用来处理返回值为null
的情况,避免出现对返回对象操作发生NullPointerException
的情况,使得代码更加健壮
Optional是容器对象,可能包含或者不包含非NULL值
常用API
- ofNullable创建Optional对象
- ifPresent对非null对象继续处理
- orElseGet对null设置默认值
- filter过滤结果
- map映射新的Optional对象
正确使用Optional
- 避免使用
Optional.isPresent
来检查实例是否存在,然后再操作,这样与if (obj != null)
的使用方式没有区别,可以使用Optional.ifPresent(u -> System.out.println(u.getName())))
- 避免使用
Optional.get
来获取对象,可能会出现NPE(NullPointerException)的问题,使用设置默认值的方式获取Optional对象,userOpt.orElseGet(() -> new User(-1, "Empty"))
- 避免使用Optional作为类或者实例属性
- 避免使用Optional作为方法的参数
1 使用Optional创建返回值
1.1 使用of创建非空对象
public String findUserById(int id) {
if (id == 1) {
return "Alice";
} else {
return null;
}
}
使用Option处理
import java.util.Optional;
public Optional<String> findUserById(int id) {
if (id == 1) {
return Optional.of("Alice");
} else {
return Optional.empty();
}
}
传入Optional.of
的方法的参数必须时非空的,否则抛出NPE,使用ofNullable来创建非空值
1.2 使用ofNullable创建可以为空的对象
User user = null;
Optional<User> userOpt = Optional.ofNullable(user);
2 对Optional的处理
2.1 使用 非空表达式 处理对象 ifPresent
如果对象存在,则对其进行处理,否则不处理
userOpt.ifPresent(u -> System.out.println(u.getName()));
2.2 设置默认值(空值下的处理)
创建Optional对象的时候,设置默认值
1 基本用法
如果对象不为null,则返回该对象;
User user = null;
User myUser = Optional.ofNullable(user).orElse(new User(-1, "Empty"))
2 表达式处理的区别
与orElse
的参数类型不同,如果对象为null,则执行表达式
User user = null;
User myUser = Optional.ofNullable(user).orElseGet(() -> new User(-1, "Empty"))
两种设置默认值方法的不同
当Optional中的对象为null的时候,orElseGet
方法并不会执行
public static void getValue() { System.out.println("getValue!"); }
User user = null;
System.out.println("orElse")
User testUser1 = Optional.ofNullable(user).orElse(getValue());
System.our.println("orElseGet")
User testUser2 = Optional.ofNullable(user).orElseGet(Main::getValue)
注意: 类名::方法名
是Java8新语法,表明该方法不一定会被调用
输出
orElse
getValue!
orElseGet
使用orElseGet的性能会更佳!
2.3 过滤值
对Optional中的对象进行按照条件进行筛选
需求:筛选id大于10的user
User user = new User(100, "zhangsan");
Optional<User> userOpt = Optional.ofNullable(user);
userOpt.filter(u -> u.id > 10).ifPresent(System.out.println(u.getName));
存在多个条件:id大于10并小于100
Predicate<User> userIdGt10 = u -> u.id > 10;
Predicate<User> userIdLt100 = u -> u.id < 100;
User use = new User(30, "lisi");
Optional<User> userOpt = Optional.ofNullable(user);
userOpt.filter(u -> userIdGt10.and(userIdLt100)).ifPresent(System.out.println(u.getName()));
使用optional进行条件过滤,使用一行代码就可以解决;如果使用if-else
代码比较冗长
2.4 转换值
将一个Optional对象转换为另一个Optional对象
需求:取出user中的Name
User user = new User(10, "zhangsan");
Optional<User> userOpt = Optional.ofNullable(user);
Optional<String> name = userOpt.map(User::getName);
name.orElseGet(() -> "empty").ifPresent(str -> System.out.println(str));
3 综合应用
对user对象设置默认值,并筛选其中长度大于10小于100的user的小写名字
Predicate<String> lenGt10 = name -> name.length() > 10;
Predicate<String> lenLt100 = name -> name.length() < 100;
User user = new User(10, "zhangsan");
Optional<User> userOpt = Optional.ofNullable(user);
userOpt.orElseGet(() -> new User(-1, "")).map(User::getName).map(String::toLowerCase).fileter(lenGt10.and(lenLt100)).ifPresent(name -> System.out.println(name));
参考:
Java8 Optional最佳指南,优雅解决空指针 https://javabetter.cn/java8/optional.html
Java8 Optional使用总结 https://www.cnblogs.com/kingsonfu/p/11009574.html