生活随笔
收集整理的這篇文章主要介紹了
如何正确使用Java8的Optional机制
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Java8帶來(lái)的函數(shù)式編程特性對(duì)于習(xí)慣命令式編程的程序員來(lái)說(shuō)還是有一定的障礙的,我們只有深入了解這些機(jī)制的方方面面才能運(yùn)用自如。Null的處理在JAVA編程中是出了try catch之外的另一個(gè)頭疼的問題,需要大量的非空判斷模板代碼,程序邏輯嵌套層次太深。尤其是對(duì)集合的使用,需要層層判空。
首先來(lái)看下Optional類的結(jié)構(gòu)圖:
1,Optional擁有兩個(gè)字段
/**??????*?Common?instance?for?{@code?empty()}.??????*/?????private?static?final?Optional<?>?EMPTY?=?new?Optional<>();??????/**??????*?If?non-null,?the?value;?if?null,?indicates?no?value?is?present??????*/? ????private?final?T?value;??1)EMPTY持有某個(gè)類型的空值結(jié)構(gòu),調(diào)用empty()返回的即是該實(shí)例
public?static<T>?Optional<T>?empty()?{?????????@SuppressWarnings("unchecked")?????????Optional<T>?t?=?(Optional<T>)?EMPTY;?????????return?t;? ????}??2)T vaule是該結(jié)構(gòu)的持有的值
2,Optional的方法
1)構(gòu)造函數(shù)
private?Optional()?{?????????this.value?=?null;?????}?private?Optional(T?value)?{?????????this.value?=?Objects.requireNonNull(value);? ????}??Optional(T value)如果vaule為null就會(huì)拋出NullPointer異常,所以對(duì)于使用的場(chǎng)景這兩個(gè)構(gòu)造器都適用.
2)生成Optional對(duì)象
有兩個(gè)方法 of(T)和ofNullable(T)
public?static?<T>?Optional<T>?of(T?value)?{?????????return?new?Optional<>(value);?????}???public?static?<T>?Optional<T>?ofNullable(T?value)?{?????????return?value?==?null???empty()?:?of(value);? ????}??of是直接調(diào)用的構(gòu)造函數(shù),因此如果T為null則會(huì)拋出空指針異常
ofNullable對(duì)null進(jìn)行了處理,會(huì)返回EMPTY的實(shí)例,因此不會(huì)出現(xiàn)異常
所以只有對(duì)于明確不會(huì)為null的對(duì)象才能直接使用of
3)獲取Optional對(duì)象的值
需要擯棄的使用方式
if(value.isPresent){
....
}else{
T t = value.get();
}
這種使用方式無(wú)異于傳統(tǒng)的if(vaule != null)
正確的使用姿勢(shì):
orElse:如果值為空則返回指定的值
orElseGet:如果值為空則調(diào)用指定的方法返回
orElseThrow:如果值為空則直接拋出異常
public?T?orElse(T?other)?{?????????return?value?!=?null???value?:?other;?????}??????public?T?orElseGet(Supplier<??extends?T>?other)?{?????????return?value?!=?null???value?:?other.get();?????}??????public?<X?extends?Throwable>?T?orElseThrow(Supplier<??extends?X>?exceptionSupplier)?throws?X?{?????????if?(value?!=?null)?{?????????????return?value;?????????}?else?{?????????????throw?exceptionSupplier.get();?????????}? ????}??一般我們使用orElse來(lái)取值,如果不存在返回默認(rèn)值.
4)Optional的中間處理
filter,map,flatMap,這幾個(gè)操作跟Stream的處理類似,只是要注意flatMap處理必須手動(dòng)指定返回類型為Optional<U>,而map會(huì)自動(dòng)將返回值包裝成Optional.舉個(gè)栗子,我們有商品很訂單的結(jié)構(gòu):
package?model;??import?java.util.List;??/**??*?@auth?gongxufan??*?@Date?2017/10/23??**/?public?class?Goods?{?????private?String?goodsName;?????private?double?price;?????private?List<Order>?orderList;??????public?String?getGoodsName()?{?????????return?goodsName;?????}??????public?void?setGoodsName(String?goodsName)?{?????????this.goodsName?=?goodsName;?????}??????public?double?getPrice()?{?????????return?price;?????}??????public?void?setPrice(double?price)?{?????????this.price?=?price;?????}??????public?List<Order>?getOrderList()?{?????????return?orderList;?????}??????public?void?setOrderList(List<Order>?orderList)?{?????????this.orderList?=?orderList;?????}? }?? package?model;??import?java.time.LocalDateTime;??/**??*?@auth?gongxufan??*?@Date?2017/10/23??**/?public?class?Order?{?????private?LocalDateTime?createTime;?????private?LocalDateTime?finishTime;?????private?String?orderName;?????private?String?orderUser;??????public?LocalDateTime?getCreateTime()?{?????????return?createTime;?????}??????public?void?setCreateTime(LocalDateTime?createTime)?{?????????this.createTime?=?createTime;?????}??????public?LocalDateTime?getFinishTime()?{?????????return?finishTime;?????}??????public?void?setFinishTime(LocalDateTime?finishTime)?{?????????this.finishTime?=?finishTime;?????}??????public?String?getOrderName()?{?????????return?orderName;?????}??????public?void?setOrderName(String?orderName)?{?????????this.orderName?=?orderName;?????}??????public?String?getOrderUser()?{?????????return?orderUser;?????}??????public?void?setOrderUser(String?orderUser)?{?????????this.orderUser?=?orderUser;?????}? }??現(xiàn)在我有一個(gè)goodsOptional
Optional<Goods>?goodsOptional?=?Optional.ofNullable(new?Goods());?現(xiàn)在我需要獲取goodsOptional里邊的orderList,應(yīng)該這樣你操作
goodsOptional.flatMap(g?->Optional.ofNullable(g.getOrderList())).orElse(Collections.emptyList())?flatMap里頭返回的是Optional<List<Order>>,然后我們?cè)偈褂胦rElse進(jìn)行unwraap.因此faltMap可以解引用更深層次的的對(duì)象鏈.
5)檢測(cè)Optional并執(zhí)行動(dòng)作
public?void?ifPresent(Consumer<??super?T>?consumer)?{?????????if?(value?!=?null)?????????????consumer.accept(value);? ????}??這是一個(gè)終端操作,不像上邊的可以進(jìn)行鏈?zhǔn)讲僮?在Optional實(shí)例使用直接調(diào)用,如果value存在則會(huì)調(diào)用指定的消費(fèi)方法.舉個(gè)栗子:
Goods?goods?=?new?Goods();??Optional<Goods>?goodsOptional?=?Optional.ofNullable(goods);??List<Order>?orderList?=?new?ArrayList<>();??goods.setOrderList(orderList);? ?goodsOptional.flatMap(g?->Optional.ofNullable(g.getOrderList())).ifPresent((v)->?System.out.println(v));??至此該類的方法和使用介紹都差不多了,最后總結(jié)需要注意的地方:
1)Optional應(yīng)該只用處理返回值,而不應(yīng)該作為類的字段或者方法的參數(shù).因?yàn)檫@樣會(huì)造成額外的復(fù)雜度.
2)使用Option應(yīng)該避免直接適應(yīng)構(gòu)造器和get,而應(yīng)該使用isElse的系列方法避免頻繁的非空判斷
3)map和flatMap要注意區(qū)分使用場(chǎng)景 ?
原文發(fā)布時(shí)間為:2017-10-31
本文作者:吹著空調(diào)蓋被子
本文來(lái)自云棲社區(qū)合作伙伴“51CTO”,了解相關(guān)信息可以關(guān)注。
總結(jié)
以上是生活随笔為你收集整理的如何正确使用Java8的Optional机制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。