美文网首页javaJava8
用Optional取代null

用Optional取代null

作者: 小鱼嘻嘻 | 来源:发表于2018-06-02 07:56 被阅读94次
null引发的问题以及为什么要避免null引用

先看一个例子

public static void main(String[] args) {
        new Person().getCar().getInsurance().getName();
    }

    static class Person {
        private Car car;

        public Car getCar() {
            return car;
        }

        public void setCar(Car car) {
            this.car = car;
        }
    }

    static class Car {
        private Insurance insurance;

        public Insurance getInsurance() {
            return insurance;
        }

        public void setInsurance(Insurance insurance) {
            this.insurance = insurance;
        }
    }

    static class Insurance {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

意思也就是说获取一个人的车的保险公司的名称。可以看到的是,并不是每一个都有车,也并不是每一个车都有保险。这样的获取是会发生NullpointException,如何避免呢?Java8之前我们可能采用防御式编程。

    Person p = new Person();
        if (p != null) {
            Car car = p.getCar();
            if (car != null) {
                Insurance insurance = car.getInsurance();
                if (insurance != null) {
                    System.out.println(insurance.getName());
                }
            }
        }

这样的代码会看着结构不清晰,可读性很差。如何解决呢?请看Java8引入的Optional。

Optional 类
  • 入门
    Optional<T> T就是需要处理的对象,当对象为空的时候返回的是一个空Optional对象,当你使用Optional.empty()是不会报空指针的。
    重构之前的数据模型
static class Person {
        private Optional<Car> car;

        public Optional<Car> getCar() {
            return car;
        }

        public void setCar(Optional<Car> car) {
            this.car = car;
        }
    }

    static class Car {
        private Optional<Insurance> insurance;

        public Optional<Insurance> getInsurance() {
            return insurance;
        }

        public void setInsurance(Optional<Insurance> insurance) {
            this.insurance = insurance;
        }
    }

    static class Insurance {
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
  • 应用Optional的几种模式
    申明一个空的Optional:Optional.empty();
    依据一个非空值创建Optional:Optional.of();
    可接受null的Optional:Optional.ofNullable();
  • 使用map从Optional中提取和转换值
       Optional<Insurance> insurance = Optional.of(new Insurance());
        Optional<String> s = insurance.map(Insurance::getName);

这种map的转换和之前的stream基本一样,只是这个是单个元素的转换而已。

  • 使用flatMap链接Optional对象
 String s1 = person.
            flatMap(Person::getCar).
            flatMap(Car::getInsurance).
            map(Insurance::getName).
            orElse("unknown");

对比我们的第一份代码这个代码结构就太清晰了,层次和逻辑也很清新。

默认行为以及解引用Optional对象
  • get() 是这些方法中最简单又最不安全的方法,如果不存在的话是会抛异常的,这个方法慎用。
  • orElse(T other) 这个的意思是允许你换一个其他的值,当返回的对象不存在的时候。
  • orElseGet(Supplier<? extends T> other) 是orElse(T other)的延迟调用版,supplier方法只有在Optional不含值的时候才调用。
  • orElseThrow(Supplier<? extends X> exceptionSupplier) 和get类型遇到Optional为空的时候回抛异常。
  • ifPresent(Consumer<? super T>) 让你能在变量值存在时执行一个作为参数传入的方法。
两个Optional对象组合

假设你试图获取保险最便宜的。

private static Optional<Insurance> getCheapestInsurance(Optional<Person> person, Optional<Car> car) {
        if (person.isPresent() && car.isPresent()) {
            return getCheapestInsurance(person.get(), car.get());
        }
        return Optional.empty();
    }

    private static Optional<Insurance> getCheapestInsurance(Person person, Car Car) {
        return null;
    }

这种并不是最优的解决方法,请看下面:

return person.flatMap(p -> car.map(c -> getCheapestInsurance(p, c))).orElse(Optional.empty());
使用filter剔除特定的值
 insurance.filter(insurance1 -> insurance1.getName().equals("AAA"))
            .ifPresent(x -> System.out.println(x));

这个filter和stream的filter也是一样的。

方法 描述
empty 返回一个空的Optional实例
filter 如果值存在并且满足提供的谓词,就返回Optional对象,否则返回空
flatMap 如果值存在,就对该值执行mapping函数调用,返回一个Optional对象,否则就返回一个空Optional
get 如果值存在就返回Optional对象,否则报异常
ifPresent 如果值存在就执行该方法,不存在什么也不做
isPresent 存在就返回true,不存在就返回false
map 如果值存在就执行mapping函数调用
of 将制定值用Optional封装之后返回,如果为空就返回一个Optional空对象
orElse 如果有值就返回值,没有就返回一个默认值
orElseGet 如果有值就返回,没有值就执行supplier函数
orElseThrow 如果有值就返回,否则抛出指定的异常

相关文章

  • 用Optional取代null

    创建Optional对象 Optional.empty():声明一个空Optional Optional.of()...

  • 用Optional取代null

    null引发的问题以及为什么要避免null引用 先看一个例子 意思也就是说获取一个人的车的保险公司的名称。可以看到...

  • Optional 取代 null?

    我们在平时编程的时候,遇到的一类Exception 要数 NullPointException, 所以我们很经常...

  • 利用Optional取代null

    由于Optional未能实现Serializable接口,若使用了某些要求序列化的库或者框架,在域模型中使用Opt...

  • java8-用Optional取代null

    Optional的主要作用:预防 Java 中著名的 NullPointerException 异常 NullPo...

  • Java8 用Optional取代null

    避免用null来表示变量的缺失! 带来的问题: java.util.Optional 在对象模型中使用Opt...

  • Java8笔记(5)

    Java8笔记(5) 用 Optional 取代 null 如何为缺失的值建模 假设你需要处理下面这样的嵌套对象,...

  • java8(六)用 Optional 取代 null

    一、null带来了哪些问题? 1)NullPointerException 是目前Java程序开发中最典型的异常。...

  • JDK8特性与使用手记

    新特性总览 lambda表达式 Stream操作数组 Optional取代null 简洁的并发编程 LocalDa...

  • JDK8新特性之Optional

    Optional是什么 java.util.Optional Jdk8提供Optional,一个可以包含null值...

网友评论

    本文标题:用Optional取代null

    本文链接:https://www.haomeiwen.com/subject/srvlsftx.html