Optional类讲解

48 阅读2分钟

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

Optional类是java8中引入的一个非常有用的类,主要用处是解决编程中的空指针异常,本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。用于避免用if判空时出现空指针异常,它就是一个包裹着对象的容器。如果值存在则 isPresent()方法会返回 true,调用 get() 方法会返回该对象。

Optional.of(T value) 该方法通过一个非 null 的 value 来构造一个 Optional,返回的 Optional 包含了 value 这个值。对于该方法,传入的参数一定不能为null,否则便会抛出 NullPointerException。

Optional<User> opt = Optional.of(user);

Optional.ofNullable(T value) 该方法和 of 方法的区别在于,传入的参数可以为null,进行三目运算,判断传入的参数是否为 null,如果为 null 的话,返回的就是 Optional.empty()。

Optional<User> opt = Optional.ofNullable(user);

Optional.empty() 该方法用来构造一个空的 Optional,即该 Optional 中不包含值。尝试访问emptyOpt变量的值会导致NoSuchElementException。

Optional<User> opt = Optional.empty();

访问Optional对象的值get()

Optional<User> opt = Optional.of(user);
User tmp = opt.get();

get方法会在值为null的时候抛出异常,我们可以用ifPresent()方法验证值是否为空

ifPresent() – 验证有值,设置Optional时做些事情

opt.ifPresent(x -> print(x)); opt.ifPresent(this::print); 

orElse()– 变空,可选为默认T

int len = opt.map(String::length).orElse(-1);  

orElseGet() – 变空可选为默认T

int len = opt. map(String::length). orElseGet(() -> slowDefault()); 

filter() – 拒绝(过滤掉)某些可选值。

opt.filter(x -> x.contains("ab")).ifPresent(this::print); 

map() – 如果存在变换值,map是可以无限级联的, 可以再深一层

 opt.map(String::trim).filter(t -> t.length() > 1).ifPresent(this::print); 

Optional空判断

Optional.ofNullable(pictureCondition)
                .map(PictureCondition::getUrl)
                .map(String::trim)
                .filter(x -> !"".equals(x))
                .orElseThrow(() -> new RuntimeException("出错啦"));

orElseThrow() – 在空可选的情况下延迟抛出exception

 opt. filter(s -> !s.isEmpty()). map(s -> s.charAt(0)). orElseThrow(IllegalArgumentException::new); 

flatMap()不会使用Optional包装Function执行的返回结果

public static String getStudentName(School school){
    return Optional.ofNullable(school)
            .flatMap(School::getTearch)
            .flatMap(Tearch::getStudent)
            .map(Student::getName).orElse("false");
}

如果某对象实例的属性本身就为Optional包装过的类型,那么就要使用flatMap方法,就像School::getTearch返回的就是Optional类型的,所以不用再使用Optional进行包装,这时就要选用flatMap方法。