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

posted on 2020-11-24 23:05  涤生-三省吾身  阅读(161)  评论(0编辑  收藏  举报

导航