java 8中的Optional

原創(chuàng)性聲明:本文完全為筆者原創(chuàng)司恳,請(qǐng)尊重筆者勞動(dòng)力绍傲。轉(zhuǎn)載務(wù)必注明原文地址。

2014年java8發(fā)布后猎塞,許多新特性被廣泛應(yīng)用杠纵。個(gè)人認(rèn)為,最高頻出現(xiàn)的就是以下三個(gè)新東西:

1.Optional
2.新的日期類Calendar
3.Lambda表達(dá)式

今天我先整理一下Optional類铝量。它有以下幾個(gè)APi方法:

1. empty
2. equal
3. filter
4. flatMap
5. get
6. hashCode
7. ifPresent
8. map
9. of
10. ofNullable
11. orElse
12. orElseGet
13. orElseThrow
14. toString
這個(gè)類的作用是什么呢银亲?(下面針對(duì)幾個(gè)常用的舉例說明)

解決java開發(fā)人員避免空指針異常而做的繁瑣的if...else處理。

比如拍谐,有一個(gè)Article類馏段,它具有屬性name,我們要判斷name屬性是否等于"java 8中的Optional"亡蓉,我們可以這樣做:

Article article = articleRepository.findOne(id);
if (article != null) {
  if (article.getName() != null) {
    if (article.getName().equal("java 8中的Optional")) {
       return true;
    } else {
       return false;
    }
  } else {
    return false;
  }
} else {
  return false;
}

這沒毛病喷舀,而且可以說代碼非常嚴(yán)謹(jǐn)元咙。只是很多if...else看上去并不好受巫员,而且其實(shí)上面的代碼看上去有很多,而功能卻很簡(jiǎn)單简识,假設(shè)上面不存在空指針問題感猛,代碼可以精簡(jiǎn)如下:

Article article = articleRepository.findOne(id);
if (article.getName().equal("java 8中的Optional")) {
    return true;
} else {
    return false;
}

但事實(shí)我們不得不去判斷空指針異常陪白,因?yàn)閿?shù)據(jù)庫中可能不存在id對(duì)應(yīng)的article膳灶,即使存在,它的name可能也是null序厉。但是Optional類允許我們這樣做:

return Optional.ofNullable(articleRepository.findOne(id)).map(c -> c.getName())
    .map(name -> name.equal("java 8中的Optional"))
    .orElse(false);

三行代碼毕箍,精簡(jiǎn)、嚴(yán)謹(jǐn)文捶、優(yōu)雅媒咳。

雖然可能初次接觸Optional可能會(huì)有點(diǎn)不容易理解。

上面的結(jié)構(gòu)其實(shí)可以這樣去理解:

return Optional.ofNullable(...) //1
      .map(...) //2
      .map(...) //3
      .orElse(...); //4

下面詳細(xì)解釋一下:

括號(hào)1中代表初始數(shù)據(jù)(article)恨搓,作為參數(shù)傳入OfNullable方法筏养,這個(gè)方法其實(shí)是構(gòu)建一個(gè)Optional封裝類,把數(shù)據(jù)articleRepository.findOne(id)的返回值包裝進(jìn)去辉浦,如果這個(gè)返回值是null,直接執(zhí)行orElse方法茎辐,也就是取false,相當(dāng)于直接return false弛槐,如果不是null依啰,執(zhí)行第一個(gè)map方法,map方法的參數(shù)是一個(gè)Lambda表達(dá)式叹誉,c代表了Optional包裝的非空數(shù)據(jù)(即articleRepository.findOne(id)的返回值,已經(jīng)確保了非空),接著c.getName()將會(huì)被執(zhí)行钧唐,返回值將會(huì)繼續(xù)被封裝成Optional匠襟,如果這個(gè)返回值(name)為null,將會(huì)執(zhí)行orElse,結(jié)果仍為return false酸舍,如果非空父腕,繼續(xù)下一個(gè)map方法,同理璧亮,第二個(gè)map方法也是一個(gè)Lambda表達(dá)式, 第一個(gè)map方法的返回值(Optional)所包裝的非空數(shù)據(jù)(name)將會(huì)被傳入第二個(gè)map方法的name參數(shù)中枝嘶,然后繼續(xù)執(zhí)行name.equal("java 8中的Optional"),后面沒有map方法了,所以這個(gè)語句的結(jié)果將會(huì)被作為整個(gè)Optional操作的結(jié)果群扶。

上面的解釋就是這樣一個(gè)Optional操作的詳細(xì)解釋竞阐,所以顯然,map方法可以無限多骆莹。雖然解釋看上去很復(fù)雜幕垦,但是習(xí)慣了這樣的思維后,其實(shí)也就那回事兒先改。

另外仇奶,map方法里是一個(gè)Lambda表達(dá)式,所以,它里面可以做更多的事情嫁艇,比如弦撩,我們希望再獲取article對(duì)象后论皆,更改一下author屬性点晴,再持久化操作, 可以這樣去修改第一個(gè)map方法:

return Optional.ofNullable(articleRepository.findOne(id))
    .map(c -> {
          c.setAuthor("dongfangyihaolan");
          articleRepository.saveAndFlush(c);
          return c.getName()
    })
    .map(name -> name.equal("java 8中的Optional"))
    .orElse(false);

它并不影響整個(gè)name的判斷陪竿,也很好的處理了更新article對(duì)象時(shí)的空指針問題屠橄。

tip: 注意,當(dāng)Lambda表達(dá)式是語句塊(有{}時(shí))礁哄,里面需要顯式的加上return 溪北, return的數(shù)據(jù)會(huì)被封裝成Optional,其包裝的數(shù)據(jù)會(huì)被作為參數(shù)傳遞至下一個(gè)map, 并執(zhí)行下一輪map茉继。

常用的方法還有一個(gè)filter蚀乔,過濾。仍以上面為例乙墙,我們希望只對(duì)有效的article執(zhí)行后面的map操作,該如何听想?

你當(dāng)然可以在jpa方法上做過濾查詢或者在return c.getName()前做是否有效判斷汉买,但是現(xiàn)在用filter也可以做到。如下:

return Optional.ofNullable(articleRepository.findOne(id))
    .filter(c -> ifEffect(c))
    .map(c -> c.getName())
    .map(name -> name.equal("java 8中的Optional"))
    .orElse(false);

ifEffect()是自定義判斷是否有效的方法。如果為false,也將執(zhí)行orElse垫卤,為true才去繼續(xù)執(zhí)行map

同樣歇盼,filter也可以用語句塊的形式评抚,完成更多的處理。

還有ifPresentget也值得一提邢笙,例如一個(gè)article被封裝好成為了Optional侍匙,假設(shè)為articleOpt,可以用articleOpt.ifPresent判斷是否為null妇汗,用articleOpt.get將封裝的數(shù)據(jù)實(shí)體取出江滨。

更多關(guān)于Optional的內(nèi)容還是自己看看官方API吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末告唆,一起剝皮案震驚了整個(gè)濱河市擒悬,隨后出現(xiàn)的幾起案子稻艰,更是在濱河造成了極大的恐慌,老刑警劉巖僧凤,帶你破解...
    沈念sama閱讀 223,207評(píng)論 6 521
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件元扔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡澎语,警方通過查閱死者的電腦和手機(jī)验懊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,455評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門尸变,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碱工,你說我怎么就攤上這事骑晶〔莼郏” “怎么了?”我有些...
    開封第一講書人閱讀 170,031評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵漫谷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我碟婆,道長(zhǎng)惕稻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,334評(píng)論 1 300
  • 正文 為了忘掉前任俺祠,我火速辦了婚禮,結(jié)果婚禮上蜘渣,老公的妹妹穿的比我還像新娘。我一直安慰自己蔫缸,他們只是感情好腿准,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,322評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拾碌,像睡著了一般吐葱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上校翔,一...
    開封第一講書人閱讀 52,895評(píng)論 1 314
  • 那天弟跑,我揣著相機(jī)與錄音,去河邊找鬼展融。 笑死窖认,一個(gè)胖子當(dāng)著我的面吹牛豫柬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扑浸,決...
    沈念sama閱讀 41,300評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼烧给,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼喝噪!你這毒婦竟也來了础嫡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,264評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤酝惧,失蹤者是張志新(化名)和其女友劉穎榴鼎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晚唇,經(jīng)...
    沈念sama閱讀 46,784評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡巫财,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,870評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哩陕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片平项。...
    茶點(diǎn)故事閱讀 40,989評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖悍及,靈堂內(nèi)的尸體忽然破棺而出闽瓢,到底是詐尸還是另有隱情,我是刑警寧澤心赶,帶...
    沈念sama閱讀 36,649評(píng)論 5 351
  • 正文 年R本政府宣布扣讼,位于F島的核電站,受9級(jí)特大地震影響缨叫,放射性物質(zhì)發(fā)生泄漏椭符。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,331評(píng)論 3 336
  • 文/蒙蒙 一弯汰、第九天 我趴在偏房一處隱蔽的房頂上張望艰山。 院中可真熱鬧,春花似錦咏闪、人聲如沸曙搬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,814評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纵装。三九已至,卻和暖如春据某,著一層夾襖步出監(jiān)牢的瞬間橡娄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,940評(píng)論 1 275
  • 我被黑心中介騙來泰國打工癣籽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挽唉,地道東北人滤祖。 一個(gè)月前我還...
    沈念sama閱讀 49,452評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瓶籽,于是被迫代替她去往敵國和親匠童。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,995評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容