每日一例 | 要想java學(xué)的好,optional少不了……
前言
在java流式編程的大家庭里,有一個(gè)類,一直會(huì)時(shí)不時(shí)的出現(xiàn)在我們的世界里,當(dāng)然你用或者不用,它就在那里,靜靜地等待著你的青睞。這個(gè)類的好處是,可以優(yōu)化很多不必要的if-else,特別是真對(duì)賦值的if-else。話不多說(shuō),我們直接來(lái)看下這個(gè)神秘的類——optional.
optional
正如它的中文含義一樣,它本身也是可選擇的,你可以根據(jù)自己的需要選擇不同的方法,以滿足你不同的需求。我們來(lái)看下它常用的方法。
構(gòu)造方式
optaional屬于工具類范疇,所有它本身不對(duì)外提供構(gòu)造方法,但是它提供了兩個(gè)靜態(tài)方法,你可以根據(jù)你的需要來(lái)構(gòu)建基于你的對(duì)象的optional(有點(diǎn)繞),它本身是基于泛型構(gòu)建的
of(T value)
直接構(gòu)建optional,不管值是否為空
ofNullable(T value)
值為空直接返回空的optional,否則調(diào)用of(T value)
ifPresent
這個(gè)方法就是它的字面意思,如果存在,然后進(jìn)行相應(yīng)的操作
String testStr = "optianal";
Optional<String> testStr1 = Optional.of(testStr);
// 如果不為空?qǐng)?zhí)行
testStr1.ifPresent(System.out::println);
我這里的用法就是,當(dāng)testStr1存在(值不空的時(shí)候),打印其值。方法本身是支持lambda表達(dá)式,所以這里我直接用了lambda表達(dá)式。
這個(gè)方法就可以很好的減少if-else,直接在ifPresent方法中,傳入你要執(zhí)行的方法即可,是不是很方便。
isPresent()
這個(gè)方法就是單純判斷optional的值是否為空,直接返回布爾值
// 值不為空為true,否則為false
if (testStr1.isPresent()) {
System.out.println("testStr1的值為空");
}
這里的值其實(shí)就指的是我們構(gòu)建的時(shí)候,傳入的對(duì)象
orElse()
如果值不為空,則返回其值,否則將傳入的值返回。這個(gè)方法也很好用,特別是在賦值的時(shí)候。
Optional<String> s3 = Optional.of("");
// 如果值不為空,則返回其值,否則將傳入的值返回
String s = s3.orElse("null");
orElseGet()
剛開始沒(méi)發(fā)現(xiàn)和上面方法有啥區(qū)別,源碼層面也看著大同小異。但在實(shí)際使用的時(shí)候,我發(fā)現(xiàn)他們還是有區(qū)別的,它需要傳入Supplier<? extends T>,這個(gè)類我查了,是用來(lái)創(chuàng)建對(duì)象的,但是不同于傳統(tǒng)的創(chuàng)建對(duì)象語(yǔ)法,它必須寫成類名::new,這就是lambda的寫法。
也就是說(shuō),這個(gè)方法其實(shí)是傳入了一個(gè)空對(duì)象
// 如果值不為空,則返回其值,否則獲取傳入的值
String s1 = s3.orElseGet(String::new);
System.out.println("s1:" +s1);
對(duì)于我這里的用法就是,如果s3的值為空的話,他會(huì)返回一個(gè)空字符串。
orElseThrow()
這個(gè)方法就和前面兩個(gè)方法很類似了,只是它的作用是,如果值為空就拋出一個(gè)異常,這個(gè)異常也是通過(guò)Supplier<? extends T>的方式構(gòu)建的,如果你需要拋出特定的異常,你可以自己定義
// 如果值不為空,則返回其值,否則拋出一個(gè)異常
String s2 = s3.orElseThrow(Exception::new);
System.out.println("s2:" +s2);
我發(fā)現(xiàn)orElse神奇的一點(diǎn)是,如果值為空,下面的System.out.println壓根都不會(huì)執(zhí)行,debug也不會(huì)走,初步推斷應(yīng)該是在編譯層面就做了預(yù)處理

但是看了反編譯的class代碼,發(fā)現(xiàn)又好像沒(méi)出來(lái),但是如果為空,直接就會(huì)拋出異常,這確實(shí)厲害了,后面再研究下,有知道的小伙伴可以告訴我。
filter()
這個(gè)方法和我們前面講stream時(shí)的方法作用是一樣的,只是這里對(duì)optional來(lái)說(shuō),如果不符合過(guò)濾條件,最后返回的是空optional,也就是說(shuō)isPresent是false。
Optional<String> sdf = s3.filter(v -> v.equals("sdf"));
System.out.println(sdf);
map()
和filter看起來(lái)類似,但是map的功能更強(qiáng)大,類似于一個(gè)加工廠,可以按照你的需求處理,最后返回你想要的結(jié)果:
Optional<Boolean> test = s3.map(v -> v.equals("test"));
Optional<String> s4 = s3.map(v -> v + "123123");
System.out.println(s4);
System.out.println(test);
flatMap()
這個(gè)方法和map基本上沒(méi)區(qū)別,源碼上也是,唯一的區(qū)別我也標(biāo)出來(lái)了

總結(jié)
今天我們分享了一個(gè)比較好用的類——Optional,這個(gè)類我覺(jué)得在實(shí)際開發(fā)中用起來(lái)應(yīng)該還是美滋滋的,至少它可以解決我們?nèi)粘i_發(fā)的兩個(gè)問(wèn)題,一個(gè)就是繁瑣的if-else,看起來(lái)也確實(shí)不夠友好,同時(shí)它可以讓我們?cè)谌粘9ぷ髦斜M可能避開空指針的運(yùn)行時(shí)異常,畢竟避免NPE是后端開發(fā)人員的最基本素養(yǎng),你說(shuō)呢?好了,今天的內(nèi)容就到這里吧,新的一周開始了,大家都要元?dú)鉂M滿哦
