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接口生成的異常

相關文章
相關標籤/搜索