Java Optional
Optional判断空值很方便,但是我们如何使用更合适,在什么情况不适合使用呢?
下面我们看下Optional 使用的几大规则:
1. Optional 和其他的Java对象一样,千万别用null 作为optional 的变量或者返回值。
2.在判断isPresent之前,不要使用get()方法. (原开发者后悔开发了get方法……^_^)
看如下代码:
public String getCustemerNameById(List<Customer> customerList, String customerId){
Optional <Customer> opt= customerList.stream().filter(c->customerId.equals(c.getCustomerId()))
.findFirst();
return opt.get().getCustomerName();
}
很容易产生空指针异常。
应该改为:
public String getCustemerNameById(List<Customer> customerList, String customerId){
Optional <Customer> opt= customerList.stream().filter(c->customerId.equals(c.getCustomerId()))
.findFirst();
return opt.isPresent()?opt.get().getCustomerName():"UNKNOWN";
}
3. 尽可能替换Optional.isPresent() and Optional.get()这种模式
最佳实践
public String getCustemerNameById(List<Customer> customerList, String customerId){
Optional <String> opt= customerList.stream().filter(c->customerId.equals(c.getCustomerId()))
.findFirst().map(c->c.getCustomerName());
// return opt.orElse("UNKNOWN");
// return opt.orElseGet(supplier.getNewCustomer().getCustomerName());
return opt.orElseThrow(()->new RuntimeException("Not found!!!"));
}
4. 不要为了链式开发而强制使用Optional.ofNullable(obj).orElseGet
//BAD
public String getData(String s){
return Optional.ofNullable(s).orElse("Default Value");
}
//Good
public String getData(String s){
return s==null?"Default Value":s;
}
5. 如果Optional 链中有内嵌Optional 或者中间值导致Optional<Optional<T>>会太复杂,尽量避免
public Optional<BigDecimal> calculateAdd(Optional<BigDecimal> first,Optional<BigDecimal> second){
return first.map(a->second.map(a::add).orElse(a)) //不推荐
.map(Optional::of)
.orElse(second);
}
//清晰的表达 推荐
public Optional<BigDecimal> calculateAdd1(Optional<BigDecimal> first,Optional<BigDecimal> second){
BigDecimal ZERO = new BigDecimal(0);
if(!first.isPresent()&&!second.isPresent()){
return Optional.empty();
}else{
return Optional.of(first.orElse(ZERO).add(second.orElse(ZERO)));
}
}
6. 不要使用Optional 类型作为属性,方法参数以及collection
7. ifPresent and Stream
//java 8
public List<Customer> existingCustomers(List<Customer> customerList){
return customerList.stream().map(CustomerRepo::findById)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
}
//java 9
public List<Customer> existingCustomers(List<Customer> customerList){
return customerList.stream().map(CustomerRepo::findById)
.flatMap(Optional::stream)
.collect(Collectors.toList());
}
Reference:
https://www.youtube.com/watch?v=fBYht
浙公网安备 33010602011771号