日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

如何正确使用Java8的Optional机制

發(fā)布時間:2025/3/20 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何正确使用Java8的Optional机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java8帶來的函數(shù)式編程特性對于習(xí)慣命令式編程的程序員來說還是有一定的障礙的,我們只有深入了解這些機(jī)制的方方面面才能運(yùn)用自如。Null的處理在JAVA編程中是出了try catch之外的另一個頭疼的問題,需要大量的非空判斷模板代碼,程序邏輯嵌套層次太深。尤其是對集合的使用,需要層層判空。

首先來看下Optional類的結(jié)構(gòu)圖:

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持有某個類型的空值結(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就會拋出NullPointer異常,所以對于使用的場景這兩個構(gòu)造器都適用.

    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是直接調(diào)用的構(gòu)造函數(shù),因此如果T為null則會拋出空指針異常

    ofNullable對null進(jìn)行了處理,會返回EMPTY的實(shí)例,因此不會出現(xiàn)異常

    所以只有對于明確不會為null的對象才能直接使用of

    3)獲取Optional對象的值

    需要擯棄的使用方式

    if(value.isPresent){

    ....

    }else{

    T t = value.get();

    }

    這種使用方式無異于傳統(tǒng)的if(vaule != null)

    正確的使用姿勢:

    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來取值,如果不存在返回默認(rèn)值.

    4)Optional的中間處理

    filter,map,flatMap,這幾個操作跟Stream的處理類似,只是要注意flatMap處理必須手動指定返回類型為Optional<U>,而map會自動將返回值包裝成Optional.舉個栗子,我們有商品很訂單的結(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)在我有一個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>>,然后我們再使用orElse進(jìn)行unwraap.因此faltMap可以解引用更深層次的的對象鏈.

    5)檢測Optional并執(zhí)行動作

  • public?void?ifPresent(Consumer<??super?T>?consumer)?{?
  • ????????if?(value?!=?null)?
  • ????????????consumer.accept(value);?
  • ????}??
  • 這是一個終端操作,不像上邊的可以進(jìn)行鏈?zhǔn)讲僮?在Optional實(shí)例使用直接調(diào)用,如果value存在則會調(diào)用指定的消費(fèi)方法.舉個栗子:

  • 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)檫@樣會造成額外的復(fù)雜度.

    2)使用Option應(yīng)該避免直接適應(yīng)構(gòu)造器和get,而應(yīng)該使用isElse的系列方法避免頻繁的非空判斷

    3)map和flatMap要注意區(qū)分使用場景 ?


    原文發(fā)布時間為:2017-10-31

    本文作者:吹著空調(diào)蓋被子

    本文來自云棲社區(qū)合作伙伴“51CTO”,了解相關(guān)信息可以關(guān)注。

    總結(jié)

    以上是生活随笔為你收集整理的如何正确使用Java8的Optional机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。