Optional
Optional.of
该方法的入参是一个非null值,如果该值为null,则抛出NullPointerException,不为Null则返回该值。
Optional.ofNullable
非Null时返回该值,为null时返回一个Optional.empty()
Optional.empty()
通过构造方法返回一个空的Optional实例。
代码语言:javascript复制Optional<User> user = Optional.ofNullable(getUserById(id));
if (user.isPresent()) {
String username = user.get().getUsername();
System.out.println("Username is: " username); // 使用 username
}
代码是优美了点 —— 但是事实上这与之前判断 null
值的代码没有本质的区别,反而用 Optional
去封装 value,增加了代码量。
Optional.ifPresent
更好的使用Optional:
代码语言:javascript复制User user = userService.getUser(userId);
Optional<User> optionalUser = Optional.ofNullable(user);
//存在值时调用ifPresent中的内容
optionalUser.ifPresent(value -> log.debug(value.getUsername()));
Consumer,适用于JDK8的函数式接口,作为lambda表达式的入参,将参数包装消费
结合Optional的源码来看,Optional中如果有值则会调用Consumer.accept(value);
orElse
代码语言:javascript复制User unknown = Optional.ofNullable(user).orElse(new User(0, "Unknown"));
orElseGet
代码语言:javascript复制User unknownGet = Optional.ofNullable(userService.getUser(userId)).orElseGet(() -> new User(0, "UnknownGet"));
两者的作用是当入参是null时,匹配自定义默认值
代码语言:javascript复制public static void main(String[] args) {
String name = Optional.of("baeldung").orElse(getRandomName());
log.info(name);
}
private static String getRandomName() {
List<String> names = new ArrayList<>();
names.add("zhangsan");
names.add("李四");
names.add("wangwu");
log.info("getRandomName() method - start");
Random random = new Random();
int index = random.nextInt(3);
log.debug("getRandomName() method - end");
return names.get(index);
}
Remember (from the Javadoc) that the Supplier method passed as an argument is only executed when *an Optional* value is not present.
区别:
- orElse与orElseGet的区别是前者的入参是一个泛型T,后者是一个函数式方法的结果。
- 即使ofNullable中的值是null,orElse中的代码也会执行
orElseThrow
当Optional中为空值时抛出异常
代码语言:javascript复制User user = Optional
.ofNullable(getUserById(id))
.orElseThrow(() -> new EntityNotFoundException("id 为 " id " 的用户没有找到"));
map
代码语言:javascript复制String password = " password ";
Optional<String> passOpt = Optional.of(password);
boolean correctPassword = passOpt.filter(pass -> pass.equals("password")).isPresent();//false
boolean password1 = passOpt.map(String::trim).filter(pass -> pass.equals("password")).isPresent();//true
filter
代码语言:javascript复制Person person = new Person("NICK",22);
Optional<Person> personOptional = Optional.ofNullable(person);
Optional<String> optionalName = personOptional
.map(Person::getName)
.orElseThrow(() -> new RuntimeException("你nameOptionalWrapper女朋友没名字!"));