Java8-關於Optional的那些事

java8出來也有一段時間了,不知大家用得還順手否?如果已經習慣於使用Lambda表達式和Stream流的人一定會經常發現一個特殊的對象:Optional類。今天我要聊的內容都跟Optional這個類有關。

好了,廢話不多說,下面進入正題。

Optional是什麼

對於Optional是個什麼,大家不要想得太複雜。簡單得說,就是Java8中新增的一個類,經常配合Stream流和Lambda表達式來使用的類。

那麼java8為啥要新增這麼一個類呢?總不會是吃飽了撐得沒事幹吧,所以既然你在java8中看到了它,說明必然有其存在的意義。

至於存在意義為何,我現在也不是很清楚。有種說法叫避免空指針異常問題。我覺得這種說法有點扯。因為我試了幾次,如果你不做任何的判斷,該拋的異常依然存在。只不過在避免非空問題的處理上確實比傳統方式順眼許多。

下面我將使用一個例子來簡單演示一下傳統避免空指針和使用Optional避免控制針,代碼示例如下:

Java8-關於Optional的那些事

由上圖可知,使用Optional後,避免空指針異常的方式會更加順眼。至少我是這麼覺得的。

既然簡單扯了一下何為Optional,那麼接下來就該詳細說說Optional的用法了。

Optional對象獲取

首先我們要能拿到一個Optional對象,那麼Optional對象又該如何拿到呢?目前獲取Optional類對象的方式有三種:of方法,ofNullable方法和empty方法。

下面的例子演示了三種獲取Optional對象的方式:

Java8-關於Optional的那些事

那麼這三種獲取Optional對象的方式有何區別呢?這個可以從源碼中找到答案。

of方法的源碼如下:

Java8-關於Optional的那些事

ofNullable方法的源碼如下:

Java8-關於Optional的那些事

empty方法的源碼如下:

Java8-關於Optional的那些事

通過對比可以發現,of方法獲取Optional對象時,要求傳入的值不能為空,而ofNullable則允許傳入值的為空,只不過值為空時,構造的是一個Optional的值為空的對象。而empty方法則直接獲取一個值為空的Optional對象。

Optional對象的常用方法

既然已經能拿到Optional對象,那麼就可以調用該對象自帶的一系列方法了。由於本人的JDK為13,所以哪些方法在JDK8上沒有,也記得不是很清,所以大家可以先熟練掌握JDK8中能用的,至於別的至少先混個臉熟。

Optional常用的方法如下:

  • isEmpty方法

isEmpty方法用來判斷該Optional對象中存儲的值是否為空,為空返回true,不為空返回false。

isEmpty的示例代碼如下:

Java8-關於Optional的那些事

執行結果如下:

Java8-關於Optional的那些事

  • isPresent方法

isPresent方法也是用來判斷Optional對象中存儲的值是否不為空的,當Optional對象中存儲的值不為空時返回true, 為空時返回false,其判斷結果與isEmpty的判斷結果相反。

isPresent方法的示例代碼如下:

Java8-關於Optional的那些事

執行結果如下:

Java8-關於Optional的那些事

  • get方法

get方法用來獲取Optional中存儲的對象值,如果存儲的的值為空,則會拋出異常。

get方法的示例代碼如下:

Java8-關於Optional的那些事

執行後結果如下:

Java8-關於Optional的那些事

  • orElse方法

orElse方法也可以獲取Optional對象中存儲的值,與get不同之處在於,當存儲值為空時,會返回orElse傳入值,而非拋出異常。

orElse方法的示例代碼如下:

Java8-關於Optional的那些事

執行結果如下:

Java8-關於Optional的那些事

  • or方法

or方法會先判斷當前Optional對象存儲的值是否為空,不為空則依然返回當前對象,若為空,則根據傳入的生產者對象來獲取另一個Opitonal對象。當然,通過該生產者對象產生的Optional對象中存儲的值不能為空。

or方法的示例代碼如下:

Java8-關於Optional的那些事

執行後結果如下:

Java8-關於Optional的那些事

  • orElseGet方法

orElseGet方法和orElse方法有些類似,都是當Optional對象存儲的值為空,根據傳入的參數來計算返回值。區別在於orElseGet是根據傳入的生產者對象來獲取,而orEles是直接將傳入的值返回。

orElseGet方法的示例代碼如下:

Java8-關於Optional的那些事

執行結果如下:

Java8-關於Optional的那些事

  • orElseThrow方法

orElseThrow方法的作用是當Optional對象存儲的值為空的時候拋出一個異常,當然,若Optional對象存儲的值不為空的時候,正常返回。orElseThrow有兩個重載版本:一個無參的,一個帶參的。無參拋出的是默認的異常,而帶參的則會拋出指定的異常。

orElseThrow方法示例代碼如下:

Java8-關於Optional的那些事

執行結果如下圖:

Java8-關於Optional的那些事

  • filter方法

filter方法是用來判斷該Optional對象中存儲的值是否符合傳入的判斷條件。

若該Optional對象中存儲的值為空,則依然返回該對象。當Optional對象中存儲的值不為空時,進行條件判斷,滿足則返回該對象,不滿足則返回一個空對象。

filter方法的示例代碼如下:

Java8-關於Optional的那些事

執行結果如下圖:

Java8-關於Optional的那些事

  • ifPrsent

ifPresent方法的作用是,當Optional對象存儲的值不為空時,通過傳入的消費者對象對該值進行處理。若存儲值為空,則不做任何處理。

ifPresent方法示例代碼如下:

Java8-關於Optional的那些事

執行結果如下:

Java8-關於Optional的那些事

  • ifPresentOrElse

ifPresentOrElse方法的作用與ifPresent方法有些類似,都是當Optional中存儲的值不為空時,使用傳入的生產者對象進行處理,區別在於ifPresentOrElse多傳入了一個線程執行體對象-Runnable, 當Optional中存儲的值為空時,執行該線程執行體,當然,僅僅是作為普通方法調用。至於我為何會這麼說,可以看如下源碼:

Java8-關於Optional的那些事

從源碼中可知,這裡是直接調用的run方法,而開啟新線程執行的前提是,需要用Thread類對象接收Runnable對象,並調用Thread類對象的start方法才可以。

下面給出ifPresentOrElse的示例代碼:

Java8-關於Optional的那些事

執行結果如下圖所示:

Java8-關於Optional的那些事

  • map

map方法是當Optional中存儲的值不為空時,將其轉換為另一種類型值的Optional對象。

map方法的示例代碼如下:

Java8-關於Optional的那些事

執行結果如下:

Java8-關於Optional的那些事

  • flatMap

flatMap方法的作用與map方法類似,都是講當前Optional對象中存儲的值經過轉換後生成另一個Optional對象,區別在於map只需要提供轉換Optional對象中值的轉換器即可,而flatMap則必須提供對Optional對象中值的處理並且轉換為哪種Optional對象的方法。

flatMap方法的示例代碼如下:

Java8-關於Optional的那些事

執行結果如下:

Java8-關於Optional的那些事

  • stream方法

stream方法的作用是將Optional對象轉換為Steam流對象。關於何為Stream流對象,也是Java8新增特性,這裡就不過多介紹。

stream方法的示例代碼如下:

Java8-關於Optional的那些事

執行結果如下圖所示:


Java8-關於Optional的那些事

最後,需要提一點的是,Java中還有與Optional類似的專門用來處理Double的OptionalDouble,專門用於處理int的OptionalInt和專門用於處理long的OptionalLong這三個類。其獲取方式和常用方法與Optional的方式都大同小異,故不再過多介紹。大家只要類比以一下就能掌握。


分享到:


相關文章: