天天看點

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

點選上方藍色字型,選擇“标星公衆号”

優質文章,第一時間送達

作者 | zjhred

來源 | http://8rr.co/hsLh

引言

在文章的開頭,先說下NPE問題,NPE問題就是,我們在開發中經常碰到的NullPointerException.假設我們有兩個類,他們的UML類圖如下圖所示

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

在這種情況下,有如下代碼  user.getAddress().getProvince();

這種寫法,在user為null時,是有可能報NullPointerException異常的。為了解決這個問題,于是采用下面的寫法

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

這種寫法是比較醜陋的,為了避免上述醜陋的寫法,讓醜陋的設計變得優雅。JAVA8提供了Optional類來優化這種寫法,接下來的正文部分進行詳細說明 API介紹 先介紹一下API,與其他文章不同的是,本文采取類比的方式來講,同時結合源碼。而不像其他文章一樣,一個個API羅列出來,讓人找不到重點。

Optional(T value),empty(),of(T value),ofNullable(T value)

這四個函數之間具有相關性,是以放在一組進行記憶。 先說明一下,Optional(T value),即構造函數,它是private權限的,不能由外部調用的。其餘三個函數是public權限,供我們所調用。那麼,Optional的本質,就是内部儲存了一個真實的值,在構造的時候,就直接判斷其值是否為空。好吧,這麼說還是比較抽象。直接上Optional(T value)構造函數的源碼,如下圖所示

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

那麼,of(T value)的源碼如下:

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

也就是說of(T value)函數内部調用了構造函數。根據構造函數的源碼我們可以得出兩個結論:

  • 通過of(T value)函數所構造出的Optional對象,當Value值為空時,依然會報NullPointerException。
  • 通過of(T value)函數所構造出的Optional對象,當Value值不為空時,能正常構造Optional對象。

除此之外呢,Optional類内部還維護一個value為null的對象,大概就是長下面這樣的

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

那麼,

empty()

的作用就是傳回EMPTY對象。 好了鋪墊了這麼多,可以說

ofNullable(T value)

的作用了,上源碼

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

好吧,大家應該都看得懂什麼意思了。相比較of(T value)的差別就是,當value值為null時, of(T value) 會報NullPointerException異常; ofNullable(T value) 不會throw Exception, ofNullable(T value) 直接傳回一個EMPTY對象。 那是不是意味着,我們在項目中隻用ofNullable函數而不用of函數呢? 不是的,一個東西存在那麼自然有存在的價值。當我們在運作過程中,不想隐藏NullPointerException。而是要立即報告,這種情況下就用Of函數。但是不得不承認,這樣的場景真的很少。部落客也僅在寫junit測試用例中用到過此函數。 2、

orElse(T other),orElseGet(Supplier extends T> other)和orElseThrow(Supplier extends X> exceptionSupplier)

這三個函數放一組進行記憶,都是在構造函數傳入的value值為null時,進行調用的。orElse和orElseGet的用法如下所示,相當于value值為null時,給予一個預設值:

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

這兩個函數的差別:當user值不為null時,orElse函數依然會執行createUser()方法,而orElseGet函數并不會執行createUser()方法,大家可自行測試。 至于orElseThrow,就是value值為null時,直接抛一個異常出去,用法如下所示

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

3、

map(Function super T, ? extends U> mapper)和flatMap(Function super T, Optional> mapper)

這兩個函數放在一組記憶,這兩個函數做的是轉換值的操作。 直接上源碼

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

這兩個函數,在函數體上沒什麼差別。唯一差別的就是入參,map函數所接受的入參類型為

Function super T, ? extends U>

Function super T, Optional>

在具體用法上,對于map而言: 如果User結構是下面這樣的

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

這時候取name的寫法如下所示

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

對于flatMap而言:  如果User結構是下面這樣的

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

這時候取name的寫法如下所示

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

4、isPresent()和ifPresent(Consumer super T> consumer) 這兩個函數放在一起記憶,

isPresent

即判斷value值是否為空,而

ifPresent

就是在value值不為空時,做一些操作。這兩個函數的源碼如下

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

需要額外說明的是,大家千萬不要把

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

給寫成

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

因為這樣寫,代碼結構依然醜陋。部落客會在後面給出正确寫法 至于

ifPresent(Consumer super T> consumer)

,用法也很簡單,如下所示

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

5、filter(Predicate super T> predicate)      不多說,直接上源碼

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

filter 方法接受一個 

Predicate

 來對 

Optional

 中包含的值進行過濾,如果包含的值滿足條件,那麼還是傳回這個 Optional;否則傳回 

Optional.empty

。 用法如下

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

如上所示,如果user的name的長度是小于6的,則傳回。如果是大于6的,則傳回一個EMPTY對象。

實戰使用

例一 在函數方法中,   以前寫法

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

JAVA8寫法

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

例二 比如,在主程式中,    以前寫法

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

JAVA8寫法

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

例三 以前寫法

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

java8寫法

mybatis判斷list為空或null_JAVA8之妙用Optional解決判斷Null為空的問題

其他的例子,不一一列舉了。不過采用這種鍊式程式設計,雖然代碼優雅了。但是,邏輯性沒那麼明顯,可讀性有所降低,大家項目中看情況酌情使用。

往期推薦

看完這篇還不了解 Nginx,那我就哭了!

[email protected]預設線程池導緻OOM問題

7000字 Redis 超詳細總結筆記總 | 收藏必備!

對MySQL的鎖了解嗎

Spring 最常用的 7 大類注解

Kafka 事務之偏移量的送出對資料的影響

中國網際網路史就是一部流氓史!

如何幹掉惡心的 SQL 注入?

Linux 最常用指令

MyBatis 事務管了解析:颠覆你心中對事務的了解!

好文章,我 在看 ❤️