最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java8 Optional原理及用法解析

 更新時(shí)間:2020年09月01日 11:33:18   作者:三月凌空  
這篇文章主要介紹了Java8 Optional原理及用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

平時(shí)開(kāi)發(fā)的工作中, 自己組內(nèi)的很多大佬經(jīng)常使用Optional的用法, 自己?jiǎn)査麄? 這個(gè)到底有什么好處呢,他們說(shuō)可以很好的規(guī)避好空指針的問(wèn)題, 我們?cè)谄綍r(shí)寫(xiě)java代碼的時(shí)候, 如果是一個(gè)新手, 肯定很多情況下都會(huì)出現(xiàn)空指針的報(bào)錯(cuò), 而java8 以后提供的Optional的問(wèn)題, 就可以很好地規(guī)避我們空指針的問(wèn)題.

空指針異常是導(dǎo)致Java應(yīng)用程序失敗的最常見(jiàn)原因。以前,為了解決空指針異常,Google公司著名的Guava項(xiàng)目引入了Optional類(lèi),Guava通過(guò)使用檢查空值的方式來(lái)防止代碼污染,它鼓勵(lì)程序員寫(xiě)更干凈的代碼。受到Google Guava的啟發(fā),Optional類(lèi)已經(jīng)成為Java 8類(lèi)庫(kù)的一部分。Optional實(shí)際上是個(gè)容器:它可以保存類(lèi)型T的值,或者僅僅保存null。Optional提供很多有用的方法,這樣我們就不用顯式進(jìn)行空值檢測(cè)。

1. 在Optional之前

在Java 8之前,程序員將返回null而不是Optional。這種方法有一些缺點(diǎn)。一種是沒(méi)有明確的方法來(lái)表示null可能是一個(gè)特殊值。相比之下,在API中返回Optional是明確的聲明,其中可能沒(méi)有值。如果我們要確保不會(huì)出現(xiàn)空指針異常,則需要對(duì)每個(gè)引用進(jìn)行顯式的空檢查,如下所示,我們都同意這是很多樣板。

// Life before Optional
  private void getIsoCode( User user){
    if (user != null) {
      Address address = user.getAddress();
      if (address != null) {
        Country country = address.getCountry();
        if (country != null) {
          String isocode = country.getIsocode();
          if (isocode != null) {
            isocode = isocode.toUpperCase();
         }
       }
     }
   }
 }

為了簡(jiǎn)化此過(guò)程,讓我們看一下如何使用Optional類(lèi),從創(chuàng)建和驗(yàn)證實(shí)例到使用它提供的不同方法并將其與返回相同類(lèi)型的其他方法組合在一起,后者才是Optional的厲害之處。

Optional類(lèi)提供了大約10種方法,我們可以使用它們來(lái)創(chuàng)建和使用Optional類(lèi),下面將介紹如何使用它們。

2. 創(chuàng)建一個(gè)Optional類(lèi)

1. Optional.of()

// 參數(shù)不能是null
Optional<Integer> optional1 = Optional.of(1);

2. Optional.ofNullable()

Optional.of()或者Optional.ofNullable():創(chuàng)建Optional對(duì)象,差別在于of不允許參數(shù)是null,而ofNullable則無(wú)限制。

// 參數(shù)可以是null
Optional<Integer> optional2 = Optional.ofNullable(null);

// 參數(shù)可以是非null
Optional<Integer> optional3 = Optional.ofNullable(2);

3. Optional.empty()

Optional.empty():所有null包裝成的Optional對(duì)象:

Optional<Integer> o1 = Optional.<Integer>empty()
Optional<Integer> o2 = Optional.ofNullable(null)
print(o1 == o2) // true

3. 判斷是否存在

1. isPresent()判斷值是否存在

Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

// isPresent判斷值是否存在
System.out.println(optional1.isPresent() == true);
System.out.println(optional2.isPresent() == false);

2. ifPresent(Consumer consumer)

ifPresent(Consumer consumer), 如果Optional對(duì)象保存的值不是null, 則調(diào)用consumer對(duì)象,否則不調(diào)用

Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

// 如果不是null,調(diào)用Consumer
optional1.ifPresent(new Consumer<Integer>() {
@Override
public void accept(Integer t) {
System.out.println("value is " + t);
}
});

// null,不調(diào)用Consumer
optional2.ifPresent(new Consumer<Integer>() {
@Override
public void accept(Integer t) {
System.out.println("value is " + t);
}
});

5. 獲取Optional里面的對(duì)象

1. get()

注意:在調(diào)用get()方法之前, 一定要先進(jìn)行isPresent()方法判斷是否存在值

//get
Optional<String> optional1 = Optional.of("javaone");
if (optional1.isPresent()){
 String value = optional1.get();
}

2. orElse(value)

返回值(如果存在);反之,返回其他。

//orElse
String nullName = null;
String name = Optional.ofNullable(nullName).orElse("default_name");

3. orElseGet(Supplier supplier)

返回值(如果存在);否則,調(diào)用other并返回該調(diào)用的結(jié)果。

該orElseGet() 方法類(lèi)似于 orElse()。但是,如果沒(méi)有Optional值,則不采用返回值,而是采用供應(yīng)商功能接口,該接口將被調(diào)用并返回調(diào)用的值:

//orElseGet
String name = Optional.ofNullable(nullName).orElseGet(() -> "john");

那么,orElse() 和orElseGet()之間有什么區(qū)別。

乍一看,這兩種方法似乎具有相同的效果。但是,事實(shí)并非如此。讓我們創(chuàng)建一些示例,以突出兩者之間的相似性和行為差異。

首先,讓我們看看它們?cè)趯?duì)象為空時(shí)的行為:

String text = null;
String defaultText = Optional.ofNullable(text).orElseGet(this::getDefaultValue);
defaultText = Optional.ofNullable(text).orElse(getDefaultValue());
public String getDefaultValue() {
  System.out.println("Getting Default Value");
  return "Default Value";
}

在上面的示例中,我們?cè)贠ptional對(duì)象中包裝了一個(gè)空文本,然后嘗試使用兩種方法中的每一種來(lái)獲取包裝后的值。副作用如下:

Getting Default Value
Getting Default Value

在每種情況下都會(huì)調(diào)用默認(rèn)方法。碰巧的是,當(dāng)不存在包裝的值時(shí),兩者 orElse() 和的 orElseGet() 工作方式完全相同。

4. orElseThrow()

值不存在則拋出異常,存在則什么不做,有點(diǎn)類(lèi)似Guava的Precoditions

Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

optional1.orElseThrow(()->{throw new IllegalStateException();});

try
{
// 拋出異常
optional2.orElseThrow(()->{throw new IllegalStateException();});
}
catch(IllegalStateException e )
{
e.printStackTrace();
}

5. 流處理

1. filter(Predicate)

判斷Optional對(duì)象中保存的值是否滿(mǎn)足Predicate,并返回新的Optional。

Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

Optional<Integer> filter1 = optional1.filter((a) -> a == null);
Optional<Integer> filter2 = optional1.filter((a) -> a == 1);
Optional<Integer> filter3 = optional2.filter((a) -> a == null);
System.out.println(filter1.isPresent());// false
System.out.println(filter2.isPresent());// true
System.out.println(filter2.get().intValue() == 1);// true
System.out.println(filter3.isPresent());// false

2. map(Function):

對(duì)Optional中保存的值進(jìn)行函數(shù)運(yùn)算,并返回新的Optional(可以是任何類(lèi)型)

Optional<Integer> optional1 = Optional.ofNullable(1);
Optional<Integer> optional2 = Optional.ofNullable(null);

Optional<String> str1Optional = optional1.map((a) -> "key" + a);
Optional<String> str2Optional = optional2.map((a) -> "key" + a);

System.out.println(str1Optional.get());// key1
System.out.println(str2Optional.isPresent());// false

3. flatMap()

功能與map()相似,差別請(qǐng)看如下代碼。flatMap方法與map方法類(lèi)似,區(qū)別在于mapping函數(shù)的返回值不同。map方法的mapping函數(shù)返回值可以是任何類(lèi)型T,而flatMap方法的mapping函數(shù)必須是Optional。

Optional<Integer> optional1 = Optional.ofNullable(1);

Optional<Optional<String>> str1Optional = optional1.map((a) -> {
return Optional.<String>of("key" + a);
});

Optional<String> str2Optional = optional1.flatMap((a) -> {
return Optional.<String>of("key" + a);
});

System.out.println(str1Optional.get().get());// key1
System.out.println(str2Optional.get());// key1

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中的HashMap源碼分析

    Java中的HashMap源碼分析

    這篇文章主要介紹了Java中的HashMap源碼分析,散列表是根據(jù)關(guān)鍵碼值(Key?value)而直接進(jìn)行訪問(wèn)的數(shù)據(jù)結(jié)構(gòu),也就是說(shuō),它通過(guò)把關(guān)鍵碼值映射到表中一個(gè)位置來(lái)訪問(wèn)記錄,以加快查找的速度,這個(gè)映射函數(shù)叫做散列函數(shù),存放記錄的數(shù)組叫做散列表,需要的朋友可以參考下
    2023-09-09
  • JAVA使用commos-fileupload實(shí)現(xiàn)文件上傳與下載實(shí)例解析

    JAVA使用commos-fileupload實(shí)現(xiàn)文件上傳與下載實(shí)例解析

    這篇文章主要介紹了JAVA使用commos-fileupload實(shí)現(xiàn)文件上傳與下載的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Java實(shí)現(xiàn)接月餅小游戲的示例代碼

    Java實(shí)現(xiàn)接月餅小游戲的示例代碼

    本文將用Java語(yǔ)言自制一個(gè)小游戲:《接月餅小游戲》,游戲規(guī)則為不要被月亮砸到,盡可能地多接月餅。文中的實(shí)現(xiàn)代碼講解清晰,感興趣的可以動(dòng)手試一試
    2022-02-02
  • Java知識(shí)點(diǎn)歸納總結(jié)

    Java知識(shí)點(diǎn)歸納總結(jié)

    本篇文章對(duì)Java的一些知識(shí)點(diǎn)進(jìn)行了歸納總結(jié)分析。需要的朋友參考下
    2013-05-05
  • Spring事件監(jiān)聽(tīng)器@EventListener與publishEvent的使用

    Spring事件監(jiān)聽(tīng)器@EventListener與publishEvent的使用

    Spring可以通過(guò)事件監(jiān)聽(tīng)器機(jī)制來(lái)處理應(yīng)用程序中的事件,本文主要介紹了Spring事件監(jiān)聽(tīng)器@EventListener與publishEvent的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • 解析如何用兩個(gè)棧來(lái)實(shí)現(xiàn)隊(duì)列的方法

    解析如何用兩個(gè)棧來(lái)實(shí)現(xiàn)隊(duì)列的方法

    本篇文章是對(duì)如何用兩個(gè)棧實(shí)現(xiàn)隊(duì)列的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • Java工作隊(duì)列代碼詳解

    Java工作隊(duì)列代碼詳解

    這篇文章主要介紹了Java工作隊(duì)列代碼詳解,涉及Round-robin 轉(zhuǎn)發(fā),消息應(yīng)答(messageacknowledgments),消息持久化(Messagedurability)等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • springboot集成flyway自動(dòng)創(chuàng)表的詳細(xì)配置

    springboot集成flyway自動(dòng)創(chuàng)表的詳細(xì)配置

    Flayway是一款數(shù)據(jù)庫(kù)版本控制管理工具,支持?jǐn)?shù)據(jù)庫(kù)版本自動(dòng)升級(jí),Migrations可以寫(xiě)成sql腳本,也可以寫(xiě)在java代碼里;本文通過(guò)實(shí)例代碼給大家介紹springboot集成flyway自動(dòng)創(chuàng)表的詳細(xì)過(guò)程,感興趣的朋友一起看看吧
    2021-06-06
  • mybatis寫(xiě)xml時(shí)數(shù)字類(lèi)型千萬(wàn)別用 !=‘‘(不為空串)進(jìn)行判斷的示例詳解

    mybatis寫(xiě)xml時(shí)數(shù)字類(lèi)型千萬(wàn)別用 !=‘‘(不為空串)進(jìn)行判斷的示例詳解

    這篇文章主要介紹了mybatis寫(xiě)xml時(shí)數(shù)字類(lèi)型千萬(wàn)別用 !=‘‘(不為空串)進(jìn)行判斷的示例詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評(píng)論

龙岩市| 雷山县| 托克逊县| 呼玛县| 鹰潭市| 武汉市| 鄂托克前旗| 泗水县| 循化| 绥江县| 上高县| 宁河县| 和平区| 富阳市| 长宁区| 塘沽区| 界首市| 嘉义市| 江城| 鄂伦春自治旗| 饶阳县| 海城市| 固安县| 霍城县| 嘉定区| 贵溪市| 沙湾县| 沙河市| 临澧县| 泰州市| 和政县| 河源市| 东台市| 龙陵县| 城固县| 新密市| 河南省| 闽侯县| 永泰县| 台湾省| 平谷区|