第七章:用Optional取代null

7.1 如何为缺失的值建模

  假如你需要你需要处理下面的嵌套对象

static class Person {
        private Car car;
        public Car getCar() {
            return car;
        }
    }
    
    class Car {
        private Insurance insurance;
        public Insurance getInsurance() {
            return insurance;
        }
    }
    
    class Insurance {
        private String name;
        public String getName() {
            return name;
        }
    }

  那么下面的代码存在什么问题呢?

public static String getCarInsuranceName(Person person) {
    return person.getCar().getInsurance().getName();
}

  这段代码看上去正常,可很容易报NullPointerException导致程序的运行终止。

解决方案:

  采用防御式检查减少NullPointerException

public static String getCarInsuranceName(Person person) {
    if(person != null) {
        Car car = person.getCar();
        if(car != null) {
            Insurance insurance = car.getInsurance();
            if(insurance != null) {
                return insurance.getName();
            }
        }
    }
    return "Unknown";
}

7.2 Optional类入门

7.2.1 使用Optional重新定义的数据模型

static class Person {
        private Optional<Car> car;
        public Optional<Car> getCar() {
            return car;
        }
    }
    
    class Car {
        private Optional<Insurance> insurance;
        public Optional<Insurance> getInsurance() {
            return insurance;
        }
    }
    
    class Insurance {
        private Optional<String> name;
        public Optional<String> getName() {
            return name;
        }
    }

7.2.2 创建Optional对象

  1. 声明一个空的Optional

Optional<Car> car = Optional.empty();

  2. 根据一个非空值创建一个Optional

Optional<Car> notNullCarOptional = Optional.of(notNullCar);

  3. 可接受null的Optional

Optional<Car> ofNullableCarOptional = Optional.ofNullable(ofNullableCar);

7.2.3 使用map从Optional对象中提取和转换值

  Optional提供了一个map方法(将实体类还原到 7.1 节的数据模型) 

public static String getCarInsuranceName(Person person) {
        // 创建一个可接受null的Optional
        Optional<Person> ofNullable = Optional.ofNullable(person);
        return ofNullable.map(Person::getCar)
                         .map(Car::getInsurance)
                         .map(Insurance::getName)
                         .orElse("Unknown");
}

  Optional提供了一个flatMap方法(将实体类还原到 7.2.1 节的数据模型)

public static String getCarInsuranceName(Person person) {
        // 创建一个可接受null的Optional
        Optional<Person> ofNullable = Optional.ofNullable(person);
        return ofNullable.flatMap(Person::getCar)
                         .flatMap(Car::getInsurance)
                         .flatMap(Insurance::getName)
                         .orElse("Unknown");
}

7.3 Optional类中的方法

方法 描述
empty     返回一个空的Optional实例
filter 如果值存在并且满足提供的谓词,就返回包含该值的Optional对象,否则返回一个空的Optional对象
flatMap 如果值存在,就对该值执行提供的mapping函数调用,返回一个Optional类型的值,否则就返回一个空的Optional对象
get 如果该值存在,将该值用Optional封装返回,否则抛出一个NoSuchElementException异常
ifPresent 如果值存在,就执行使用该值的方法调用,否则什么也不做
isPresent 如果值存在就范湖true,否则返回false
map 如果值存在,就对该值执行提供的mapping函数调用
of 将指定值用Optional封装之后返回,如果该值为null,则抛出异常
ofNullable 将指定值用Optional封装之后返回,如果该值为null,则返回一个空的Optional对象
orElse 如果有值则将其返回,否则返回一个默认值
orElseGet 如果有值则将其返回,否则返回一个由指定的Supplier接口生成的值
orElseThrow 如果有值则将其返回,否则抛出一个由指定的Supplier接口生成的异常

 

 

 

 

 

 

 

 

 

 

 

 

 

 

备注:

摘自文献:《Java8实战》(中文版)《Java8 in Action》(英文版)

 

代码(GitHub地址): https://github.com/changlezhong/java8InAction

 

posted on 2018-06-16 19:29  changlezhong  阅读(140)  评论(0)    收藏  举报

导航