Java8新特性之:Optional
一. 用Optional取代null
1. Optional類
java.util.Optional<T>是一個封裝Optional值的類。
變數存在時,Optional類只是對類進行簡單的封裝。變數不存在時,缺失的值會被建模成一個“空”的Optional物件,由方法Optional.empty()返回。
Optional.empty()方法是一個靜態工廠方法,它返回Optional類的特定單一例項。
使用Optional而不是null的一個非常重要而又實際的語義區別:
宣告變數時使用Optional<T>而不是具體的Object,這句宣告非常清楚地表明瞭這裡發生變數的缺失是允許的。
2. 應用Optional的幾種模式
建立Optional物件
-- 宣告一個空的Optional
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介面生成的異常 |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/430/viewspace-2815410/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ?Java8新特性之Optional類Java
- java8 新特性之Optional 類Java
- java8特性 Optional 工具類Java
- Java8新特性之空指標異常的剋星Optional類Java指標
- 【Java8新特性】不瞭解Optional類,簡歷上別說你懂Java8!!Java
- java8 新特性之方法引用Java
- Java8新特性探索之Stream介面Java
- Java8新特性之時間APIJavaAPI
- java8 新特性之Lambda 表示式Java
- java8 新特性之預設方法Java
- Java 8 新特性---Optional類Java
- JAVA8新特性Java
- Java8 新特性Java
- java8 新特性之函式式介面Java函式
- JDK1.8新特性值OptionalJDK
- Java 8新特性(三):Optional類Java
- Java8新特性探索之函式式介面Java函式
- Java8新特性 - LambdaJava
- Java8的新特性Java
- JAVA8新特性用法Java
- Java8 Optional類Java
- Java8新特性探索之新日期時間庫Java
- Java8新特性實踐Java
- java8新特性stream流Java
- Java8 新特性詳解Java
- Java8新特性系列-LambdaJava
- Java8新特性--Stream APIJavaAPI
- java8的新特性之lambda表示式和方法引用Java
- Java8新特性(一)-Lambda表示式Java
- Java8新特性(1):Lambda表示式Java
- Java8常用的新特性總結Java
- Java8新特性都到碗裡來Java
- 講講Java8的Optional類Java
- 好程式設計師分享java8新特性之Lambda表示式程式設計師Java
- Java8新特性之日期-時間APIJavaAPI
- 【java8新特性】蘭姆達表示式Java
- Java8 新特性 —— Stream 流式程式設計Java程式設計
- Java8的新特性--函式式介面Java函式