简述Java8 Optional

77 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第32天,点击查看活动详情

前言

Optionaljava8提供的新特性,它是一个可容纳null值的容器对象。Optional提供了ofNullable()of()方法来构建Optional对象,它可以保存类型T的值或者只保存null,这样我们就不用显示进行空值检测;

示例

我们来看一下如何使用Optional来避免null值的判断:

if (this.value != null) {
   setValue(this.value);
}

在使用Optional之前,我们差不多是按照上面的代码来处理业务逻辑的;下面我们来看看如何改造成Optional:

Optional.ofNullable(this.value).ifPresent(value->setValue(value));

上面代码拆解成两步:

1.先把未知的this.value包装成一个Optional对象;

2.通过Optional提供的api实现this.value不为null时调用业务逻辑;

defaultValue = 0;
if(this.value != null){
 return this.value;
}else{
 return defaultValue;
}

如果this.value不为null,那么直接返回this.value;否则返回默认值defaultValue;我们可以使用Optional进行以下改造:

return Optional.ofNullable(this.value).orElse(defaultValue);

如果获取默认值的方式比较复杂,我们还可以使用另一种方式:

return Optional.ofNullable(this.value).orElseGet(()->{
 Integer defaultValue = 0;
 // TODO
 // 执行获取默认值
 return defaultValue;
});

如果我们在拿不到非空值的情况下需要抛异常,那么我们可以使用orElseThrow()方法:

return Optional.ofNullable(this.value).orElseThrow(() -> new IllegalArgumentException("Argument 'value' cannot be null or blank."));

this.value值为null时,里面会抛出IllegalArgumentException异常;

除了使用orElse()方法来避免null值的判断,我们还使用map()层层递进:

User user = ......
if(user != null){
 String userName = user.getUserName();
 if(userName!=null){
   return userName.toUpperCase();
}else{
   return null;
}
}else{
 return null;
}

我们针对上述这种多层嵌套判断的代码,可以使用map()方法来降低这种复杂性:

User user = ......
Optional userOptional = Optional.ofNullable(user);
return userOptional.map(u->u.getUserName())
.map(name->name.toUpperCase())
.orElse(null);

我们还可以试一试使用filter()方法:

List<User> list = new ArrayList<>();
​
for(User u: users){
 if(u!=null&&u.getUserName().length()>6){
   list.add(u);
}
}

如果User中的UserName长度大于6的话,那么就放进列表list中;我们可以尝试用filter()方法来进行调整:

List<User> list = new ArrayList<>();
​
for(User u: users){
 Optional.ofNullable(u)
  .filter(u->u.getUserName().length()>6)
  .ifPresent(u->list.add(u));
}