生活随笔
收集整理的這篇文章主要介紹了
如何正确使用Java8的Optional机制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Java8帶來的函數式編程特性對于習慣命令式編程的程序員來說還是有一定的障礙的,我們只有深入了解這些機制的方方面面才能運用自如。Null的處理在JAVA編程中是出了try catch之外的另一個頭疼的問題,需要大量的非空判斷模板代碼,程序邏輯嵌套層次太深。尤其是對集合的使用,需要層層判空。
首先來看下Optional類的結構圖:
1,Optional擁有兩個字段
/**??????*?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持有某個類型的空值結構,調用empty()返回的即是該實例
public?static<T>?Optional<T>?empty()?{?????????@SuppressWarnings("unchecked")?????????Optional<T>?t?=?(Optional<T>)?EMPTY;?????????return?t;? ????}??2)T vaule是該結構的持有的值
2,Optional的方法
1)構造函數
private?Optional()?{?????????this.value?=?null;?????}?private?Optional(T?value)?{?????????this.value?=?Objects.requireNonNull(value);? ????}??Optional(T value)如果vaule為null就會拋出NullPointer異常,所以對于使用的場景這兩個構造器都適用.
2)生成Optional對象
有兩個方法 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是直接調用的構造函數,因此如果T為null則會拋出空指針異常
ofNullable對null進行了處理,會返回EMPTY的實例,因此不會出現異常
所以只有對于明確不會為null的對象才能直接使用of
3)獲取Optional對象的值
需要擯棄的使用方式
if(value.isPresent){
....
}else{
T t = value.get();
}
這種使用方式無異于傳統的if(vaule != null)
正確的使用姿勢:
orElse:如果值為空則返回指定的值
orElseGet:如果值為空則調用指定的方法返回
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來取值,如果不存在返回默認值.
4)Optional的中間處理
filter,map,flatMap,這幾個操作跟Stream的處理類似,只是要注意flatMap處理必須手動指定返回類型為Optional<U>,而map會自動將返回值包裝成Optional.舉個栗子,我們有商品很訂單的結構:
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;?????}? }??現在我有一個goodsOptional
Optional<Goods>?goodsOptional?=?Optional.ofNullable(new?Goods());?現在我需要獲取goodsOptional里邊的orderList,應該這樣你操作
goodsOptional.flatMap(g?->Optional.ofNullable(g.getOrderList())).orElse(Collections.emptyList())?flatMap里頭返回的是Optional<List<Order>>,然后我們再使用orElse進行unwraap.因此faltMap可以解引用更深層次的的對象鏈.
5)檢測Optional并執行動作
public?void?ifPresent(Consumer<??super?T>?consumer)?{?????????if?(value?!=?null)?????????????consumer.accept(value);? ????}??這是一個終端操作,不像上邊的可以進行鏈式操作.在Optional實例使用直接調用,如果value存在則會調用指定的消費方法.舉個栗子:
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));??至此該類的方法和使用介紹都差不多了,最后總結需要注意的地方:
1)Optional應該只用處理返回值,而不應該作為類的字段或者方法的參數.因為這樣會造成額外的復雜度.
2)使用Option應該避免直接適應構造器和get,而應該使用isElse的系列方法避免頻繁的非空判斷
3)map和flatMap要注意區分使用場景 ?
原文發布時間為:2017-10-31
本文作者:吹著空調蓋被子
本文來自云棲社區合作伙伴“51CTO”,了解相關信息可以關注。
總結
以上是生活随笔為你收集整理的如何正确使用Java8的Optional机制的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。