chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

JAVA8提供了Optional類來優(yōu)化這種寫法

Linux愛好者 ? 來源:CSDN ? 作者:zjhred ? 2022-04-24 15:18 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

引言

在文章的開頭,先說下NPE問題,NPE問題就是,我們在開發(fā)中經(jīng)常碰到的NullPointerException.假設(shè)我們有兩個(gè)類,他們的UML類圖如下圖所示

9b4c56a8-c39e-11ec-bce3-dac502259ad0.png

在這種情況下,有如下代碼

user.getAddress().getProvince();

這種寫法,在user為null時(shí),是有可能報(bào)NullPointerException異常的。為了解決這個(gè)問題,于是采用下面的寫法

if(user!=null){
Addressaddress=user.getAddress();
if(address!=null){
Stringprovince=address.getProvince();
}
}

這種寫法是比較丑陋的,為了避免上述丑陋的寫法,讓丑陋的設(shè)計(jì)變得優(yōu)雅。JAVA8提供了Optional類來優(yōu)化這種寫法,接下來的正文部分進(jìn)行詳細(xì)說明

一個(gè)連載多年還在繼續(xù)更新的免費(fèi)教程:http://blog.didispace.com/spring-boot-learning-2x/

API介紹

先介紹一下API,與其他文章不同的是,本文采取類比的方式來講,同時(shí)結(jié)合源碼。而不像其他文章一樣,一個(gè)個(gè)API羅列出來,讓人找不到重點(diǎn)。

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

這四個(gè)函數(shù)之間具有相關(guān)性,因此放在一組進(jìn)行記憶。

先說明一下,Optional(T value),即構(gòu)造函數(shù),它是private權(quán)限的,不能由外部調(diào)用的。其余三個(gè)函數(shù)是public權(quán)限,供我們所調(diào)用。那么,Optional的本質(zhì),就是內(nèi)部儲(chǔ)存了一個(gè)真實(shí)的值,在構(gòu)造的時(shí)候,就直接判斷其值是否為空。好吧,這么說還是比較抽象。直接上Optional(T value)構(gòu)造函數(shù)的源碼,如下圖所示

9b5ee322-c39e-11ec-bce3-dac502259ad0.png

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

publicstaticOptionalof(Tvalue){
returnnewOptional<>(value);
}

也就是說of(T value)函數(shù)內(nèi)部調(diào)用了構(gòu)造函數(shù)。根據(jù)構(gòu)造函數(shù)的源碼我們可以得出兩個(gè)結(jié)論:

  • 通過of(T value)函數(shù)所構(gòu)造出的Optional對象,當(dāng)Value值為空時(shí),依然會(huì)報(bào)NullPointerException。
  • 通過of(T value)函數(shù)所構(gòu)造出的Optional對象,當(dāng)Value值不為空時(shí),能正常構(gòu)造Optional對象。

除此之外呢,Optional類內(nèi)部還維護(hù)一個(gè)value為null的對象,大概就是長下面這樣的

publicfinalclassOptional<T>{
//省略....
privatestaticfinalOptionalEMPTY=newOptional<>();
privateOptional(){
this.value=null;
}
//省略...
publicstaticOptionalempty(){
@SuppressWarnings("unchecked")
Optionalt=(Optional)EMPTY;
returnt;
}
}

那么,empty()的作用就是返回EMPTY對象。

好了鋪墊了這么多,可以說ofNullable(T value)的作用了,上源碼

publicstaticOptionalofNullable(Tvalue){
returnvalue==null?empty():of(value);
}

好吧,大家應(yīng)該都看得懂什么意思了。相比較of(T value)的區(qū)別就是,當(dāng)value值為null時(shí),of(T value)會(huì)報(bào)NullPointerException異常;ofNullable(T value)不會(huì)throw Exception,ofNullable(T value)直接返回一個(gè)EMPTY對象。

那是不是意味著,我們在項(xiàng)目中只用ofNullable函數(shù)而不用of函數(shù)呢?

不是的,一個(gè)東西存在那么自然有存在的價(jià)值。當(dāng)我們在運(yùn)行過程中,不想隱藏NullPointerException。而是要立即報(bào)告,這種情況下就用Of函數(shù)。但是不得不承認(rèn),這樣的場景真的很少。博主也僅在寫junit測試用例中用到過此函數(shù)。

2、orElse(T other),orElseGet(Supplier other)和orElseThrow(Supplier exceptionSupplier)

這三個(gè)函數(shù)放一組進(jìn)行記憶,都是在構(gòu)造函數(shù)傳入的value值為null時(shí),進(jìn)行調(diào)用的。orElseorElseGet的用法如下所示,相當(dāng)于value值為null時(shí),給予一個(gè)默認(rèn)值:

@Test
publicvoidtest(){
Useruser=null;
user=Optional.ofNullable(user).orElse(createUser());
user=Optional.ofNullable(user).orElseGet(()->createUser());

}
publicUsercreateUser(){
Useruser=newUser();
user.setName("zhangsan");
returnuser;
}

這兩個(gè)函數(shù)的區(qū)別:當(dāng)user值不為null時(shí),orElse函數(shù)依然會(huì)執(zhí)行createUser()方法,而orElseGet函數(shù)并不會(huì)執(zhí)行createUser()方法,大家可自行測試。

至于orElseThrow,就是value值為null時(shí),直接拋一個(gè)異常出去,用法如下所示

Useruser=null;
Optional.ofNullable(user).orElseThrow(()->newException("用戶不存在"));

3、map(Function mapper)和flatMap(Function> mapper)

這兩個(gè)函數(shù)放在一組記憶,這兩個(gè)函數(shù)做的是轉(zhuǎn)換值的操作。

直接上源碼

publicfinalclassOptional<T>{
//省略....
publicOptionalmap(FunctionsuperT,?extendsU>mapper){
Objects.requireNonNull(mapper);
if(!isPresent())
returnempty();
else{
returnOptional.ofNullable(mapper.apply(value));
}
}
//省略...
publicOptionalflatMap(FunctionsuperT,Optional>mapper){
Objects.requireNonNull(mapper);
if(!isPresent())
returnempty();
else{
returnObjects.requireNonNull(mapper.apply(value));
}
}
}

這兩個(gè)函數(shù),在函數(shù)體上沒什么區(qū)別。唯一區(qū)別的就是入?yún)ⅲ琺ap函數(shù)所接受的入?yún)㈩愋蜑?code style="font-size:14px;padding:2px 4px;margin-right:2px;margin-left:2px;color:rgb(30,107,184);background-color:rgba(27,31,35,.05);font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;">Function,而flapMap的入?yún)㈩愋蜑?code style="font-size:14px;padding:2px 4px;margin-right:2px;margin-left:2px;color:rgb(30,107,184);background-color:rgba(27,31,35,.05);font-family:'Operator Mono', Consolas, Monaco, Menlo, monospace;">Function>。

在具體用法上,對于map而言:

如果User結(jié)構(gòu)是下面這樣的

publicclassUser{
privateStringname;
publicStringgetName(){
returnname;
}
}

這時(shí)候取name的寫法如下所示

Stringcity=Optional.ofNullable(user).map(u->u.getName()).get();

對于flatMap而言:

如果User結(jié)構(gòu)是下面這樣的

publicclassUser{
privateStringname;
publicOptionalgetName(){
returnOptional.ofNullable(name);
}
}

這時(shí)候取name的寫法如下所示

Stringcity=Optional.ofNullable(user).flatMap(u->u.getName()).get();

4、isPresent()和ifPresent(Consumer consumer)

這兩個(gè)函數(shù)放在一起記憶,isPresent即判斷value值是否為空,而ifPresent就是在value值不為空時(shí),做一些操作。這兩個(gè)函數(shù)的源碼如下

publicfinalclassOptional<T>{
//省略....
publicbooleanisPresent(){
returnvalue!=null;
}
//省略...
publicvoidifPresent(ConsumersuperT>consumer){
if(value!=null)
consumer.accept(value);
}
}

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

if(user!=null){
//TODO:dosomething
}

給寫成

Useruser=Optional.ofNullable(user);
if(Optional.isPresent()){
//TODO:dosomething
}

因?yàn)檫@樣寫,代碼結(jié)構(gòu)依然丑陋。博主會(huì)在后面給出正確寫法

至于ifPresent(Consumer consumer),用法也很簡單,如下所示

Optional.ofNullable(user).ifPresent(u->{
//TODO:dosomething
});

5、filter(Predicate predicate)

不多說,直接上源碼

publicfinalclassOptional<T>{
//省略....
Objects.requireNonNull(predicate);
if(!isPresent())
returnthis;
else
returnpredicate.test(value)?this:empty();
}

filter 方法接受一個(gè) Predicate 來對 Optional 中包含的值進(jìn)行過濾,如果包含的值滿足條件,那么還是返回這個(gè) Optional;否則返回 Optional.empty。

用法如下

Optionaluser1=Optional.ofNullable(user).filter(u->u.getName().length()<6);

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

一個(gè)連載多年還在繼續(xù)更新的免費(fèi)教程:http://blog.didispace.com/spring-boot-learning-2x/

實(shí)戰(zhàn)使用

例一

在函數(shù)方法中

以前寫法

publicStringgetCity(Useruser)throwsException{
if(user!=null){
if(user.getAddress()!=null){
Addressaddress=user.getAddress();
if(address.getCity()!=null){
returnaddress.getCity();
}
}
}
thrownewExcpetion("取值錯(cuò)誤");
}

JAVA8寫法

publicStringgetCity(Useruser)throwsException{
returnOptional.ofNullable(user)
.map(u->u.getAddress())
.map(a->a.getCity())
.orElseThrow(()->newException("取指錯(cuò)誤"));
}

例二

比如,在主程序中

以前寫法

if(user!=null){
dosomething(user);
}

JAVA8寫法

Optional.ofNullable(user)
.ifPresent(u->{
dosomething(u);
});

例三

以前寫法

publicUsergetUser(Useruser)throwsException{
if(user!=null){
Stringname=user.getName();
if("zhangsan".equals(name)){
returnuser;
}
}else{
user=newUser();
user.setName("zhangsan");
returnuser;
}
}

java8寫法

publicUsergetUser(Useruser){
returnOptional.ofNullable(user)
.filter(u->"zhangsan".equals(u.getName()))
.orElseGet(()->{
Useruser1=newUser();
user1.setName("zhangsan");
returnuser1;
});
}

其他的例子,不一一列舉了。不過采用這種鏈?zhǔn)?a href="http://www.brongaenegriffin.com/v/tag/1315/" target="_blank">編程,雖然代碼優(yōu)雅了。但是,邏輯性沒那么明顯,可讀性有所降低,大家項(xiàng)目中看情況酌情使用。

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    2992

    瀏覽量

    114737
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1926

    瀏覽量

    65500

原文標(biāo)題:Java8 判空新寫法!

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點(diǎn)推薦

    超六網(wǎng)線水晶頭和六水晶頭通用嗎

    8P8C(8位置8接觸)設(shè)計(jì),接觸片間距為1.02mm(ISO/IEC 11801標(biāo)準(zhǔn))。 通常為單排排列,適用于六非屏蔽(UTP)或屏蔽(STP)網(wǎng)線。 接觸片厚度約0.4mm,材
    的頭像 發(fā)表于 10-13 10:32 ?145次閱讀
    超六<b class='flag-5'>類</b>網(wǎng)線水晶頭和六<b class='flag-5'>類</b>水晶頭通用嗎

    使用ROCm?優(yōu)化并部署YOLOv8模型

    作者:AVNET 李鑫杰 一,YOLOv8介紹? YOLOv8 由 Ultralytics 于 2023 年 1 月 10 日發(fā)布,在準(zhǔn)確性和速度方面提供前沿的性能。YOLOv
    的頭像 發(fā)表于 09-24 18:32 ?179次閱讀
    使用ROCm?<b class='flag-5'>優(yōu)化</b>并部署YOLOv<b class='flag-5'>8</b>模型

    stm32cubemx在聯(lián)網(wǎng)時(shí)無法啟動(dòng)是怎么回事?

    多次重裝,換上了最新的版本,仍沒有解決問題。后來又重新安裝了java,無論是24,21,還是java8也都沒用。 之后偶然間打開了,同時(shí)發(fā)現(xiàn)我的WiFi掉了。我就懷疑跟聯(lián)網(wǎng)有問題。我測試了加速器,發(fā)現(xiàn)跟加速器沒有關(guān)系,cubemx就是只能斷網(wǎng)的情況下才能打開。
    發(fā)表于 08-01 08:00

    VirtualLab:光柵的優(yōu)化與分析

    光柵是光學(xué)工程師使用的最基本的工具。為了設(shè)計(jì)和分析這類組件,快速物理光學(xué)建模和設(shè)計(jì)軟件VirtualLab Fusion為用戶提供許多有用的工具。其中包括參數(shù)優(yōu)化,以輕松優(yōu)化系統(tǒng),以
    發(fā)表于 05-23 08:49

    VirtualLab Fusion應(yīng)用:非近軸衍射分束器的設(shè)計(jì)與優(yōu)化

    難度。VirtualLab Fusion為光學(xué)工程師提供幾個(gè)工具幫助他們完成這項(xiàng)任務(wù)。 為了說明一般工作流程,我們展示兩個(gè)案例:在第一個(gè)案例中,我們采用迭代傅里葉變換算法(IFT
    發(fā)表于 03-10 08:56

    VirtualLab Fusion應(yīng)用:使用自定義的評價(jià)函數(shù)優(yōu)化高NA分束器

    摘要 由于相位和結(jié)構(gòu)之間的直接關(guān)系,衍射分束鏡通常采用一定的傍軸近似設(shè)計(jì),這些算法也提供這種近似,反之亦然。在非傍軸或甚至高NA分束器的情況下,這些近似將引入一些不準(zhǔn)確性,因此,
    發(fā)表于 03-07 08:54

    Java的SPI機(jī)制詳解

    接口規(guī)范以及可以發(fā)現(xiàn)接口實(shí)現(xiàn)的機(jī)制,而不需要實(shí)現(xiàn)接口。 SPI機(jī)制在Java中應(yīng)用廣泛。例如:JDBC中的數(shù)據(jù)庫連接驅(qū)動(dòng)使用SPI機(jī)制,只定義數(shù)據(jù)庫連接接口的規(guī)范,而具體實(shí)現(xiàn)由各大數(shù)據(jù)庫廠商實(shí)現(xiàn),不同數(shù)據(jù)庫的實(shí)現(xiàn)不同,我們常用的mysql的驅(qū)動(dòng)也實(shí)現(xiàn)
    的頭像 發(fā)表于 03-05 11:35 ?990次閱讀
    <b class='flag-5'>Java</b>的SPI機(jī)制詳解

    VirtualLab Fusion應(yīng)用:傾斜光柵的魯棒性優(yōu)化

    摘要 由于制造過程中潛在的不準(zhǔn)確性,對于一個(gè)好的光柵設(shè)計(jì)來說,面對光柵參數(shù)的微小變化,提供穩(wěn)健的結(jié)果是至關(guān)重要的。VirtualLab Fusion為光學(xué)工程師提供各種工具,可以將這種
    發(fā)表于 02-19 08:58

    SSM框架在Java開發(fā)中的應(yīng)用 如何使用SSM進(jìn)行web開發(fā)

    SSM框架,即Spring、SpringMVC和MyBatis的整合,是Java Web開發(fā)中常用的技術(shù)棧。它通過分層架構(gòu),實(shí)現(xiàn)視圖、控制、業(yè)務(wù)邏輯和數(shù)據(jù)訪問的分離,提高了代碼的可維護(hù)性和可擴(kuò)展性
    的頭像 發(fā)表于 12-16 17:28 ?1948次閱讀

    Java 23功能介紹

    Java 23 包含全新和更新的 Java 語言功能、核心 API 以及 JVM,同時(shí)適合新的 Java 開發(fā)者和高級開發(fā)者。從?IntelliJ IDEA 2024.2?開始已支持 Java
    的頭像 發(fā)表于 12-04 10:02 ?1321次閱讀
    <b class='flag-5'>Java</b> 23功能介紹

    Java集合API的改進(jìn)介紹

    解答這些問題。 我們將逐步學(xué)習(xí) Java 集合優(yōu)化過程,并按版本逐一對比分析。主要討論的焦點(diǎn)將包括 JDK 1.0、1.2、1.4、1.5、1.6、1.8、9、10、11 和 21 版本的
    的頭像 發(fā)表于 11-22 11:12 ?763次閱讀
    <b class='flag-5'>Java</b>集合API的改進(jìn)介紹

    Java 枚舉與策略模式、函數(shù)式接口的結(jié)合:實(shí)現(xiàn)高內(nèi)聚低耦合的設(shè)計(jì)

    作者:京東物流 楊唯一 一、Java 枚舉 Java 枚舉是一個(gè)特殊的,一般表示一組常量,比如一年的 4 個(gè)季節(jié),一年的 12 個(gè)月份,一個(gè)星期的 7 天,方向有東南西北等。 我們
    的頭像 發(fā)表于 11-21 14:06 ?797次閱讀

    基于Java的工具Power Stage Designer

    電子發(fā)燒友網(wǎng)站提供《基于Java的工具Power Stage Designer.pdf》資料免費(fèi)下載
    發(fā)表于 11-14 16:01 ?20次下載
    基于<b class='flag-5'>Java</b>的工具Power Stage Designer

    56水晶頭區(qū)別明顯嗎

    :其內(nèi)部的8根觸點(diǎn)則是上下錯(cuò)開分成兩排排列的。 二、銅芯規(guī)格 五水晶頭:其銅芯相對較細(xì),通常在0.45毫米到0.51毫米之間。 六水晶頭:其銅芯相對較粗,通常在0.52毫米到0.58毫米之間。
    的頭像 發(fā)表于 11-07 10:23 ?2763次閱讀

    使用Arthas火焰圖工具的Java應(yīng)用性能分析和優(yōu)化經(jīng)驗(yàn)

    分享作者在使用Arthas火焰圖工具進(jìn)行Java應(yīng)用性能分析和優(yōu)化的經(jīng)驗(yàn)。
    的頭像 發(fā)表于 10-28 09:27 ?1822次閱讀
    使用Arthas火焰圖工具的<b class='flag-5'>Java</b>應(yīng)用性能分析和<b class='flag-5'>優(yōu)化</b>經(jīng)驗(yàn)