JDK8中Optional類巧用之判空操作
前言
相信大家肯定所有的開發(fā)者都對Java8里面的所有的東西都感興趣,雖然目前的 JDK 已經更新到 JDK17 了,但是我相信,現(xiàn)在很多公司使用的還都是 JDK8 甚至是 JDK7,但是,就算是有些公司已經升級到 JDK8 但是對于 JDK8 里面的一些東西的使用,卻沒有使用的淋漓盡致。 今天就給大家放出幾個 JDK8 里面比較好用的。
JDK8
大家都是知道 JDK8 就開始使用 Lambda 表達式,但是很多不管是在教程上還是在其他的書籍上,都沒有說在實際開發(fā)的時候去使用上這個 Lambda 表達式,而且包括 JDK8 里面的一些新的類,也都沒有引入,所以阿粉在這里想要給大家安利一波使用方面的知識。
Optional類
這個類對于大家來說,是一個非常重要的類,不知道大家有沒有被 java.lang.NullPointerException 瘋狂的折磨過,不管是新人開發(fā)還是老開發(fā),遇到這個問題的時候,都是頭大的很,因為我們要在代碼里面去瘋狂的判斷是否是null,如果不是 null 需要怎么處理,如果是 null 需要怎么處理,反正就是你要是想解決 java.lang.NullPointerException 這個問題,就免不了去加一些判斷條件,而 Optional 這個類,則是幫你優(yōu)雅的處理 null 的問題。
我們先看一組 Java7 中的一些判斷空的實現(xiàn):
User user = usersMapper.selectUserById(userId);
String userName = user.getUserName();
if(user!= null){
if(userName != null && !userName.isEmpty()){
.....
}
}
阿粉相信大家一定都寫過這個樣子的代碼,因為我們不知道SQL查詢出來的數據中是否包含了我們的 Users 對象,如果要是 Users 對象,那么就會無情的出現(xiàn) java.lang.NullPointerException 這個空指針異常,這時候就很尷尬了,老開發(fā)一臉懵逼,我竟然還有的地方沒有驗證?
但是驗證了之后,你就會發(fā)現(xiàn)代碼量是非常的大,而且有點不太美觀,我們再來對比一下 JDK8 中,給我們提供的方法來進行驗證的方式。
User user = usersMapper.selectUserById(userId);
Optional.ofNullable(user)
.map(User::getUserName)
.ifPresent(userName->{
....
}
大家看這種鏈式編程,ofNullable() 方法給我們提供了判斷 user 是不是空,并且去校驗 userName,如果存在,然后執(zhí)行下面的邏輯,相比較 JDK7 的內容,相信大家看起來的話肯定是沒有 JDK7 中的表現(xiàn)的那么的明顯,但是大家看代碼是不是發(fā)現(xiàn)已經被處理的妥妥的了。而且非常的優(yōu)雅。
相信大家肯定都看過一些教程,上面會寫到:
User user = usersMapper.selectUserById(userId);
Optional<User> userOptional = Optional.ofNullable(user);
Optional<String> str = userOptional.map(User::getUserName);
....
但是相對于代碼的可讀性來說,我們肯定還是希望使用 JDK7 上面的判斷來進行判斷,但是這種 JDK8 的鏈式編程,在一定程度上減少了代碼量,并且開發(fā)效率也會相對應的提升。
如果大家不信,我們可以來運行一下我們的代碼,然后看一下效果。
Optional.ofNullable(user)
.map(User::getUserName)
.ifPresent(userName->{
System.out.println("用戶UserName不為空");
});

大家看,是不是就出現(xiàn)了我們想要的結果,一個判斷 null 的操作,瞬間變得高大上了,而且代碼的逼格瞬間上升一個檔次。
對于 Optional 類,在 Java8 實戰(zhàn)中給出了很多的方法,阿粉也是給大家摘取了一下,做了個總結,
- ofNullable 方法 :將指定值用Optional封裝之后返回,如果該值為null,則返回一個空的Optional對象
- empty 方法 :返回一個空的Optional實例
- filter 方法 :如果值存在并且滿足提供的謂詞,就返回包含該值的Optional對象;否則返回一個空的 Optional對象
- flatMap 方法 :如果值存在,就對該值執(zhí)行提供的mapping函數調用,返回一個Optional類型的值,否則就返 回一個空的Optional對象
- get 方法 :如果該值存在,將該值用Optional封裝返回,否則拋出一個NoSuchElementException異常
- ifPresent 方法 :如果值存在,就執(zhí)行使用該值的方法調用,否則什么也不做
- isPresent 方法 :如果值存在就返回true,否則返回false
- map 方法 :如果值存在,就對該值執(zhí)行提供的mapping函數調用
- of 方法 :將指定值用Optional封裝之后返回,如果該值為null,則拋出一個NullPointerException異常
- orElse 方法:如果有值則將其返回,否則返回一個默認值
- orElseGet 方法 :如果有值則將其返回,否則返回一個由指定的Supplier接口生成的值
- orElseThrow 方法 :如果有值則將其返回,否則拋出一個由指定的Supplier接口生成的異常
大家看這些方法是不是都有很多相似的,比如 map,flatMap,還有orElse,orElseGet,orElseThrow 方法
map 和 flatMap 比較:
這兩個都是做 轉換值 的操作,區(qū)別就是入參的類型不是一樣的,map的入參是 Function<? super T, ? extends U> mapper 而 flatMap 入參則是 Function<? super T, Optional<U> > mapper 。
入參的不同也就導致了他們獲取返回值也是不同的,map中獲取的返回值自動被Optional包裝,flatMap中返回值保持不變,但必須是Optional類型。
這么一看總是感覺不太對的樣子,我們去源碼里面看看是什么樣子的。
map:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
flatMap:
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Objects.requireNonNull(mapper.apply(value));
}
}
map 方法參數中的函數 mapper 輸出的是值,然后 map 方法會使用 Optional.ofNullable 將其包裝為 Optional;而 flatMap 要求參數中的函數 mapper 輸出的就是 Optional。
一個是比較聰明的,另外一個就相對來說不是那么聰明了,人家會自己包裝呀,是不是?
同樣的比較還有 orElse,orElseGet,orElseThrow 但是這個阿粉就不再給大家絮叨了,因為上面的方法解釋上都很明顯的能看到了。
Lambda 表達式
Lambda 表達式實際上就是相當于是一個匿名內部類,他就是讓我們開發(fā)的人把函數當成參數傳遞給某個方法,然后把代碼當做數據去處理。
阿粉相信大家肯定都了解這塊,就比如說下面的代碼對比:
Java7:
List<String> stringList = Arrays.asList("1", "2", "3");
for (String st:stringList) {
System.out.println(st);
}
Java8:
Arrays.asList("1", "2", "3").forEach((String st)->{
System.out.println(st);
});
同樣的一個循環(huán),我們肯定想用第二種寫法不是么?
va8:
Arrays.asList("1", "2", "3").forEach((String st)->{
System.out.println(st);
});
同樣的一個循環(huán),我們肯定想用第二種寫法不是么?
Java8 實際上在從發(fā)布開始,很多公司都在用,但是也有很多人依舊選擇是 Java7,因為不想改變自己的學習風格,阿粉相信大家如果是一個決心在開發(fā)領域一直做下去的人,那么肯定會保持一個不斷學習的心,所以,你是這樣的人么?
總結
到此這篇關于JDK8中Optional類巧用之判空的文章就介紹到這了,更多相關JDK8 Optional類判空內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Hibernate中Session.get()方法和load()方法的詳細比較
今天小編就為大家分享一篇關于Hibernate中Session.get()方法和load()方法的詳細比較,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
AbstractProcessor擴展MapStruct自動生成實體映射工具類
這篇文章主要為大家介紹了AbstractProcessor擴展MapStruct自動生成實體映射工具類實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01
解析Java中的隊列和用LinkedList集合模擬隊列的方法
這篇文章主要介紹了解析Java中的隊列和用LinkedList集合模擬隊列的方法,相關算法的實現(xiàn)也是ACM中的常見題目,需要的朋友可以參考下2015-08-08
Spring使用AOP完成統(tǒng)一結果封裝實例demo
這篇文章主要介紹了Spring使用AOP完成統(tǒng)一結果封裝,本文通過實現(xiàn)demo給大家詳細講解,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-02-02
SpringBoot監(jiān)聽應用程序啟動的生命周期事件的四種方法
在 Spring Boot 中,監(jiān)聽應用程序啟動的生命周期事件有多種方法,本文給大家就介紹了四種監(jiān)聽應用程序啟動的生命周期事件的方法,并通過代碼示例講解的非常詳細,具有一定的參考價值,需要的朋友可以參考下2024-07-07

