Java8新特性之:Optional

一. 用Optional取代nulljava

    1. Optional类安全

        java.util.Optional<T>是一个封装Optional值的类。app

        变量存在时,Optional类只是对类进行简单的封装。变量不存在时,缺失的值会被建模成一个“空”的Optional对象,由方法Optional.empty()返回。ide

        Optional.empty()方法是一个静态工厂方法,它返回Optional类的特定单一实例。函数

        使用Optional而不是null的一个很是重要而又实际的语义区别:spa

              声明变量时使用Optional<T>而不是具体的Object,这句声明很是清楚地代表了这里发生变量的缺失是容许的。对象

    2. 应用Optional的几种模式接口

        建立Optional对象get

          -- 声明一个空的Optionalit

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

          -- 依据一个非空值建立Optional

               Optional<Car> optCar = Optional.of(car); //若是car是一个null,这段代码会当即抛出NullPointException,而不是等到试图访问car的属性值时才返回一个错误。

          -- 可接受null的Optional(实现序列化的域模型时使用)

              Optional<Car> optCar = Optional.ofNullable(car); //建立一个容许null值的Optional对象,若是car是null,那么获得的Optional对象就是个空对象

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

public class Person {     //有人有车,有人没车
    private Optional<Car> car;
    public Optional<Car> getCar() { return car;}
}
public class Car {     //有的车有保险,有的车没有保险
    private Optional<Insurance> insurance;
    public Optional<Insurance> getInsurance() { return insurance;}
}
public class Insurance {    //保险公司必定有名字,若是有保险公司没有名字则是出错状况
    private String name;
    public String getName() { return name;}
}
Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
Optional<String> name = optInsurance.map(Insurance::getName)

        使用flatMap连接Optional对象

            使用流时,flatMap方法接受一个函数做为参数,这个函数的返回值时另外一个流。这个方法会应用到流中的每个函数,最终造成一个新的流的流。可是flatMap会用流的内容替换每一个新生成的流。即,由方法生成的各个流会被合并或扁平化为一个单一的流。

 Optional<Person> optPerson = Optional.of(person);
          Optional<String> name =  
                                                    optPerson.map(Person::getCar)
                                                                     .map(Car::getInsurance)  //错误代码
                                                                     .map(Insurance::getName)

            getCar返回的是Optional<Car>类型的对象,因此第一个map获得的结果是Optional<Optional<Car>>类型的对象。所以他对getInsurance 的调用是非法的。不支持getInsurance方法。

            使用flatMap会捋平两层结构的Optional为一个包含了Car的单层结构。

      Optional<String> name =  
                                                    optPerson.flatMap(Person::getCar)
                                                                     .flatMap(Car::getInsurance)
                                                                     .map(Insurance::getName)
                                                                     .orElse(""Unknown); //若是Optional结果为空,设置默认值

        默认行为及解引用Optional对象

            -- get()是这些方法中最简单最不安全的方法。若是存在变量,他直接返回封装的变量值,不然抛出NoSuchElementException;

            -- orElse(T other)容许你在Optional对象不包含值时提供一个默认值;

            -- orElseGet(Supplier<? extends T> other)是orElse方法的延迟调用版,Supplier方法只有在Optional对象不含值时才执行调用。若是建立默认值是耗时费力的工做,应该采起这种方式,或你须要很是肯定某个方法仅在Optional为空时才调用,也能够考虑该方法(这种状况有严格的限制条件);

            -- orElseThrow(Supplier<? extends X> exceptionalSupplier)和get方法很是相似,当Optional对象为空时都会抛出异常,但使用orElseThrow你能够定制但愿抛出的异常;

            -- ifPresent(Consumer<? super T>)让你能在变量值存在时执行一个做为参数传入的方法,不然就不进行任何操做。

        两个Optional对象组合

public Optional<Insurance> nullSafeFindCheapestInsurance(Optional<Person> person, Optional<Car> car) {
    return person.flatMap(p -> car.map(c -> findCheapestInsurance(p, c)));
}

        使用filter剔除特定的值

//找出年龄大于或等于minAge参数的Person所对应的保险公司列表
public String getCarInsuranceName(Optional<Person> person, int minAge) {
    return person.filter(p -> p.getAge() >= minAge)
        .flatMap(Person::getCar)
        .flatMap(Car::getInsurance)
        .map(Insurance::getName)
        .orElse("Unknown");
}

            Optional和Stream接口有不少相似的方法。

            Optional类的方法

方法

描述

empty

返回一个空的Optional实例

filter

若是值存在而且知足提供的谓词,就返回包含该值的Optional对象;不然返回一个空的Optional对象

flatMap

若是值存在,就对该值执行提供的mapping函数调用,返回一个Optional类型的值,不然就返回一个空的Optional对象

get

若是值存在,就将被Optional封装的值返回,不然抛出一个NoSunchElementException异常

ifPresent

若是值存在,就执行使用该值的方法调用,不然什么也不作

isPresent

若是值存在就返回true,不然返回false

map

若是值存在,就对该值执行提供提供的mapping函数调用

of

将指定值用Optional封装以后返回,若是该值为null,则抛出一个NullPointException异常

ofNullable

将指定值用Optional封装以后返回,若是该值为null,则返回一个空的Optional对象

orElse

若是有值则将其返回,不然返回一个默认值

orElseGet

若是有值则将其返回,不然返回一个由指定的Supplier接口生成的值

OrElseThrow

若是有值则将其返回,不然抛出一个指定的Supplier接口生成的异常

相关文章
相关标签/搜索