国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java 8th 函數(shù)式編程:Optional 類型

RayKr / 3512人閱讀

摘要:當(dāng)滿足條件時執(zhí)行傳入的參數(shù)化操作。最后提醒一點,好用但不能濫用,在設(shè)計一個接口方法時是否采取類型返回需要斟酌,一味的使用會讓代碼變得比較啰嗦,反而破壞了代碼的簡潔性。鑒于作者水平有限,文中不免有錯誤之處,歡迎批評指正個人博客

NullPointException 可以說是所有 java 程序員都遇到過的一個異常,雖然 java 從設(shè)計之初就力圖讓程序員脫離指針的苦海,但是指針確實是實際存在的,而 java 設(shè)計者也只能是讓指針在 java 語言中變得更加簡單、易用,而不能完全的將其剔除,所以才有了我們?nèi)粘K姷降年P(guān)鍵字 null

空指針異常是一個運行時異常,對于這一類異常,如果沒有明確的處理策略,那么最佳實踐在于讓程序早點掛掉,但是很多場景下不是開發(fā)人員沒有具體的處理策略,而是根本沒有意識到空指針異常的存在。當(dāng)異常真的發(fā)生的時候,處理策略也很簡單,在存在異常的地方添加一個 if 語句判定即可,但是這樣的應(yīng)對策略會讓我們的程序出現(xiàn)越來越多的 null 判定。一個良好的程序設(shè)計應(yīng)該讓代碼中盡量少出現(xiàn) null 關(guān)鍵字,而 8th 所提供的 Optional 類則在減少 NullPointException 的同時,也提升了代碼的美觀度。但首先我們需要明確的是它并 不是對 null 關(guān)鍵字的替代策略,而是對于 null 判定提供了一種更加優(yōu)雅的實現(xiàn),從而盡可能地避免 NullPointException

下面通過一個小示例直觀感受一下,假設(shè)我們需要返回一個字符串的長度,如果不借助第三方工具類,我們需要調(diào)用 str.length() 方法:

if(null == str) { // 空指針判定
    return 0;
}
return str.length();

如果采用 Optional 類,實現(xiàn)如下:

return Optional.ofNullable(str).map(String::length).orElse(0);

Optional 的代碼相對更加簡潔,當(dāng)代碼量較大時,我們很容易忘記進行 null 判定,但是使用 Optional 類則會避免這類問題。

一. 基本使用 1.1 Optional 對象的創(chuàng)建

創(chuàng)建空對象

Optional optStr = Optional.empty();

上面的示例代碼調(diào)用 empty() 方法創(chuàng)建了一個空的 Optional 對象型。

創(chuàng)建對象:不允許我空

Optional 提供了方法 of() 用于創(chuàng)建非空對象,該方法要求傳入的參數(shù)不能為空,否則拋 NullPointException,示例如下:

Optional optStr = Optional.of(str);  // 當(dāng)str為null的時候,將拋出NullPointException

創(chuàng)建對象:允許為空

如果不能確定傳入的參數(shù)是否存在 null 值的可能性,則可以用 Optional 的 ofNullable() 方法創(chuàng)建對象,如果入?yún)?null 則創(chuàng)建一個空對象。示例如下:

Optional optStr = Optional.ofNullable(str);  // 如果str是null,則創(chuàng)建一個空對象
1.2 流式數(shù)據(jù)處理

流式數(shù)據(jù)處理也是 8th 給我們帶來的一個重量級新特性,讓我們對集合的操作變得更加簡潔和高效,本系列下一篇將對流式數(shù)據(jù)處理進行全面的講解。Optional 類也提供了兩個基本的流失處理:映射和過濾。

為了演示,我們設(shè)計了一個 User 類,如下:

public class User {
    private long id;
    private String name;
    private int age;
    private Optional phone;
    private Optional email;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 省略setter和getter
}

手機和郵箱不是一個人的必須有的,所以我們利用 Optional 類定義。

映射:map 與 flatMap

映射是將輸入轉(zhuǎn)換成另外一種形式的輸出的操作,比如前面例子中我們輸入字符串,而輸出的是字符串的長度,這就是一種映射,我們利用方法 map() 進行實現(xiàn)。假設(shè)我們希望獲得一個人的姓名,我們可以如下實現(xiàn):

String name = Optional.ofNullable(user).map(User::getName).orElse("no name");

這樣當(dāng)入?yún)?user 不為空的時候則返回其 name,否則返回 no name。如我我們希望通過上面方式得到 phone 或 email,利用上面的方式則行不通了,因為 map 之后返回的是 Optional,我們把這種稱為 Optional 嵌套,我們必須再 map 一次才能拿到我們想要的結(jié)果:

long phone = optUser.map(User::getPhone).map(Optional::get).orElse(-1L);

其實這個時候更好的方式是利用 flatMap,一步拿到我們想要的結(jié)果:

long phone = optUser.flatMap(User::getPhone).orElse(-1L);

flapMap 可以將方法返回的各個流扁平化成為一個流,具體在下一篇專門講流式數(shù)據(jù)處理的文章中細說。

過濾:fliter

filiter,顧名思義是過濾的操作,我們可以將過濾操作做為參數(shù)傳遞給該方法以實現(xiàn)過濾目的,假如我們希望篩選 18 周歲以上的成年人,則可以實現(xiàn)如下:

optUser.filter(u -> u.getAge() >= 18).ifPresent(u -> System.out.println("Adult:" + u));
1.3 默認行為

默認行為是當(dāng) Optional 在不滿足條件時所執(zhí)行的操作,比如在上面的例子中我們使用的 orElse() 就是一個默認操作,用于在 Optional 對象為空時執(zhí)行特定操作,當(dāng)然也有一些默認操作是當(dāng)滿足條件的對象存在時執(zhí)行的操作。

get()

get 方法用于獲取變量的值,但是當(dāng)變量不存在時則會拋出 NoSuchElementException,所以如果不確定變量是否存在則不建議使用

orElse(T other)

當(dāng) Optional 的變量不滿足給定條件時,則執(zhí)行 orElse,比如前面當(dāng) str 為 null 時返回 0。

orElseGet(Supplier expectionSupplier)

如果條件不成立時需要執(zhí)行相對復(fù)雜的邏輯而不是簡單的返回操作,則可以使用 orElseGet 實現(xiàn):

long phone = optUser.map(User::getPhone).map(Optional::get).orElseGet(() -> {
    // do something here
    return -1L;
});

orElseThrow(Supplier expectionSupplier)

get() 方法類似,都是在不滿足條件時返回異常,不過這里我們可以指定返回的異常類型。

ifPresent(Consumer)

當(dāng)滿足條件時執(zhí)行傳入的參數(shù)化操作。

二. 注意事項

Optional 是一個 final 類且未實現(xiàn)任何接口,所以當(dāng)我們在利用該類包裝定義類的屬性的時候,如果我們定義的類有序列化的需求,那么因為 Optional 沒有實現(xiàn) Serializable 接口,這個時候執(zhí)行序列化操作就會有問題:

public class User implements Serializable {
    private long id;
    private String name;
    private int age;
    private Optional phone;  // 不能序列化
    private Optional email;  // 不能序列化
}

不過我們可以采用如下替換策略 Optinal:

private long phone;

public Optional getPhone() {
    return Optional.ofNullable(this.phone);
}

看來 Optional 類在設(shè)計的時候就沒有考慮將它作為類的字段使用。

最后提醒一點,Optional 好用但不能濫用,在設(shè)計一個接口方法時是否采取 Optional 類型返回需要斟酌,一味的使用會讓代碼變得比較啰嗦,反而破壞了代碼的簡潔性。

鑒于作者水平有限,文中不免有錯誤之處,歡迎批評指正
個人博客:www.zhenchao.org

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/70647.html

相關(guān)文章

  • Java 8th 函數(shù)編程:lambda 表達

    摘要:自定義函數(shù)式接口我們在前面例子中實現(xiàn)的蘋果篩選接口就是一個函數(shù)式接口定義如下,正因為如此我們可以將篩選邏輯參數(shù)化,并應(yīng)用表達式僅包含一個抽象方法,依照定義可以將其視為一個函數(shù)式接口。 Lambda 表達式是 java 8th 給我們帶來的幾個重量級新特性之一,借用 lambda 表達式可以讓我們的程序設(shè)計更加簡潔。最近新的項目摒棄了 6th 版本,全面基于 8th 進行開發(fā),本文將探討...

    luffyZh 評論0 收藏0
  • Java8新特性總覽

    摘要:新特性總覽標(biāo)簽本文主要介紹的新特性,包括表達式方法引用流默認方法組合式異步編程新的時間,等等各個方面。還有對應(yīng)的和類型的函數(shù)連接字符串廣義的歸約匯總起始值,映射方法,二元結(jié)合二元結(jié)合。使用并行流時要注意避免共享可變狀態(tài)。 Java8新特性總覽 標(biāo)簽: java [TOC] 本文主要介紹 Java 8 的新特性,包括 Lambda 表達式、方法引用、流(Stream API)、默認方...

    mayaohua 評論0 收藏0
  • Java8學(xué)習(xí)小記

    摘要:但有一個限制它們不能修改定義的方法的局部變量的內(nèi)容。如前所述,這種限制存在的原因在于局部變量保存在棧上,并且隱式表示它們僅限于其所在線程。 2014年,Oracle發(fā)布了Java8新版本。對于Java來說,這顯然是一個具有里程碑意義的版本。尤其是那函數(shù)式編程的功能,避開了Java那煩瑣的語法所帶來的麻煩。 這可以算是一篇Java8的學(xué)習(xí)筆記。將Java8一些常見的一些特性作了一個概要的...

    CHENGKANG 評論0 收藏0
  • Java8實用技能

    大概一年多之前,我對java8的理解還僅限一些只言片語的文章之上,后來出于對函數(shù)式編程的興趣,買了本參考書看了一遍,然后放在了書架上,后來,當(dāng)我接手大客戶應(yīng)用的開發(fā)工作之后,java8的一些工具,對我的效率有了不小的提升,因此想記錄一下java8的一些常用場景,我希望這會成為一個小字典,能讓我免于頻繁翻書,但是總能找到自己想找的知識。 用于舉例的model: @Data public class ...

    microcosm1994 評論0 收藏0
  • Introducing FP in Java8

    摘要:函數(shù)副作用會給程序設(shè)計帶來不必要的麻煩,引入潛在的,并降低程序的可讀性。所以只能采用這種曲線救國的方式。則是把這種曲線救國拿到了臺面上,并昭告天下,同時還對提供了一些語法支持。是自由變量,提供執(zhí)行上下文,觸發(fā)閉包執(zhí)行。 背景 自從2013年放棄了Java就再也沒有碰過。期間Java還發(fā)布了重大更新:引入lambda,但是那會兒我已經(jīng)玩了一段時間Scala,對Java已經(jīng)瞧不上眼。相比S...

    Prasanta 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<