标签:extends 取值 java 私有 col sum turn 千万 option
一、背景
1. Optional类主要解决空指针异常的问题,避免显式判断空指针,减少null的防御性检查
2. 借鉴了google guava的Optional类
3. Optinal类里有一个字段value,主要就是对value是否为Null的判断和操作
二、创建Optional类的实例,1个构造方法,3个静态方法
1. 构造方法 private Optional(T value),因为是私有的,不能被外部访问,也就不能调用构造方法创建对象,会报空指针异常
private Optional(T value) { this.value = Objects.requireNonNull(value); }
2. of()静态方法,底层调用私有构造方法,依然会报空指针异常
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
Optional<String> optStr1 = Optional.of("optional");
3. empty()静态方法,不报空指针,返回一个值为null的Optional对象
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
Optional<String> optStr = Optional.empty();
4. ofNullable()静态方法,底层调用empty()和of()方法,如果传入的值为null,就返回值为null的Optional对象,否则返回值不为null的Optional对象,建议使用
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
Optional<String> optStr2 = Optional.ofNullable(null);
三、Optional的使用
1. get()方法,谨慎使用,返回包装对象的实际值,null会抛NoSuchElementException异常
2.isPresent() vs ifPresent()
isPresent()方法,谨慎使用,判断包装对象的实际值是否非空
ifPresent()方法,接收一个Consumer对象,如果值不为空,执行Consumer对象的accept()方法(有一个参数无返回值)
注意:千万不要这样写,因为仍然要判断null,跟不使用Optional没区别
User user = Optional.ofNullable(user); if (Optional.isPresent()){ // TODO: do something }
3. filter()方法,接收一个Predicate对象,即一个判断条件,用于对Optional对象进行过滤
Optional<User> user1 = Optional.ofNullable(user).filter(u -> u.getName().length()<6);
4. map() vs flatMap() 用于值转换
map()方法,接收一个Function<? super T, ? extends U>对象,用Function函数进行计算
flatMap()方法,接收一个Function<? super T, Optional<U>>对象,用Function函数进行计算
5. orElse() vs orElseGet() vs orElseThrow()
orElse()方法,值为null,则返回默认值;即使值不为null,仍然会执行orElse(),不建议使用
orElseGet()方法,接收一个Supplier对象,用Supplier对象的get()方法作为默认值,当值不为null时,不会执行orElseGet(),建议使用
orElseThrow()方法,接收一个Supplier对象,Supplier对象必须返回一个异常
四、实际场景
1.
public String getCity(User user) throws Exception{ if(user!=null){ if(user.getAddress()!=null){ Address address = user.getAddress(); if(address.getCity()!=null){ return address.getCity(); } } } throw new Excpetion("取值错误"); } public String getCity(User user) throws Exception{ return Optional.ofNullable(user) .map(u-> u.getAddress()) .map(a->a.getCity()) .orElseThrow(()->new Exception("取指错误")); }
2.
if(user!=null){ dosomething(user); } Optional.ofNullable(user) .ifPresent(u->{ dosomething(u); });
3.
public User getUser(User user) throws Exception{ if(user!=null){ String name = user.getName(); if("zhangsan".equals(name)){ return user; } }else{ user = new User(); user.setName("zhangsan"); return user; } } public User getUser(User user) { return Optional.ofNullable(user) .filter(u->"zhangsan".equals(u.getName())) .orElseGet(()-> { User user1 = new User(); user1.setName("zhangsan"); return user1; }); }
参考:
https://www.jianshu.com/p/d81a5f7c9c4e
https://www.cnblogs.com/rjzheng/p/9163246.html
标签:extends 取值 java 私有 col sum turn 千万 option
原文地址:https://www.cnblogs.com/june0816/p/11442923.html