目錄
一. 直覺感受
二.基本上使用
1.物件建立
三. 注意事项
首頁 Java java教程 Java8 新特性之 Optional 類

Java8 新特性之 Optional 類

Feb 23, 2017 am 10:30 AM
java8 optional類 新特性

摘要: Optional不是對null關鍵字的替代,而是對於null判定提供了一種更優雅的實作

NullPointException可以說是所有java程式設計師都遇到的異常,雖然java從設計之初就試圖讓程式設計師脫離指標的苦海,但是指標確實是實際存在的,而java設計者也只能是讓指標在java語言中變得更加簡單、易用,而不能完全的將其剔除,所以才有了我們日常所見的關鍵字

null
登入後複製
登入後複製



空指標異常是一個運行時異常,對於這一類異常,如果沒有明確的處理策略,那麼最佳實踐在於讓程式早點掛掉,但是很多場景下,不是開發人員沒有具體的處理策略,而是根本沒有意識到空指標異常的存在。當異常真的發生的時候,處理策略也很簡單,在存在異常的地方添加一個if語句判定即可,但是這樣的應對策略會讓我們的程序出現越來越多的null判定,我們知道一個很好的程式設計,應該讓程式碼中盡量少出現null關鍵字,而java8所提供的

Optional
登入後複製

類別則在減少NullPointException的同時,也提升了程式碼的美觀。但首先我們需要明確的是,它並 不是對

null
登入後複製
登入後複製
關鍵字的一種替代,而是對於null判定提供了一種更優雅的實現,從而避免NullPointException

一. 直覺感受

假設我們需要回傳一個字串的長度,如果不借助第三方工具類,我們需要呼叫

str.length()
登入後複製

方法:

if(null == str) { // 空指標判定
   return 0;
}
return str.length();
如果採用Optional類,實作如下:

return Optional.ofNullable(str).map(String::length).orElse(0);
Optional的程式碼相對更加簡潔,當程式碼量較大時,我們很容易忘記進行null判定,但是使用Optional類別則會避免這類問題。

二.基本上使用

1.物件建立

#建立空白物件
##Optional上面的範例程式碼呼叫

empty()
登入後複製

方法建立了一個空的

Optional<String>
登入後複製

物件類型。



建立物件:不允許為空
Optional提供了方法

of()
登入後複製

用於建立非空對象,該方法要求傳入的參數不能為空,否則拋

NullPointException
登入後複製

,範例如下:


Optional<String> optStr = Optional.of(str);  // 當str為null的時候,將拋出NullPointException

建立物件:允許為空
如果無法確定傳入的參數是否存在null值的可能性,則可以用Optional的

ofNullable()
登入後複製

方法建立對象,如果入參為null,則建立一個空物件。範例如下:


Optional<String> optStr = Optional.ofNullable(str);  // 如果str是null,則建立一個空物件

2.串流處理

串流處理也是java8帶給我們的一個重量級新特性,讓我們對集合的操作變得更加簡潔和高效,下一篇關於java8新特性的文章,將對流失處理進行全面的講解。這裡Optional也提供了兩個基本的流失處理:映射和過濾。


為了演示,我們設計了一個

User
登入後複製

類,如下:



#

/**
 * @author: zhenchao.Wang 2016-9-24 15:36:56
 */
public class User {
    /** 用户编号 */
    private long id;
    private String name;
    private int age;
    private Optional phone;
    private Optional<String> email;
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // 省略setter和getter
}
登入後複製

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



映射:map與flatMap
映射是將輸入轉換成另外一種形式的輸出的操作,例如前面例子中,我們輸入字串,而輸出的是字串的長度,這就是一種隱射,我們利用方法

map()
登入後複製

得以實現。假設我們希望取得一個人的姓名,那麼我們可以如下實作:


String name = Optional.ofNullable(user).map(User::getName).orElse("no name");
這樣當入參user不為空的時候則返回其name,否則返回

no name
登入後複製

 如我我們希望通過上面方式得到phone或email,利用上面的方式則行不通了,因為map之後返回的是Optional,我們把這種稱為Optional嵌套,我們必須在map一次才能拿到我們想要的結果:


long phone = optUser.map(User::getPhone).map(Optional: :get).orElse(-1L);
其實這個時候,更好的方式是利用flatMap,一步拿到我們想要的結果:

long phone = optUser.flatMap(User:: getPhone).orElse(-1L);
flapMap可以將方法傳回的各個流扁平化成為一個流,具體在下一篇專門講流式處理的文章中細說。


過濾:fliter
filiter,顧名思義是過濾的操作,我們可以將過濾操作做為參數傳遞給該方法,從而實現過濾目的,加入我們希望篩選18歲以上的成年人,則可以實現如下:


optUser.filter(u -> u.getAge() >= 18).ifPresent(u -> System.out.println("Adult:" + u));
登入後複製

3.預設行為


預設行為是當Optional為不滿足條件時所執行的操作,例如在上面的範例中我們使用的

orElse()
登入後複製

就是一个默认操作,用于在Optional对象为空时执行特定操作,当然也有一些默认操作是当满足条件的对象存在时执行的操作。

get()

get用于获取变量的值,但是当变量不存在时则会抛出

NoSuchElementException
登入後複製

,所以如果不确定变量是否存在,则不建议使用

orElse(T other)

当Optional的变量不满足给定条件时,则执行orElse,比如前面当str为null时,返回0。

orElseGet(Supplier<? extends X> expectionSupplier)
登入後複製

如果条件不成立时,需要执行相对复杂的逻辑,而不是简单的返回操作,则可以使用orElseGet实现:

long phone = optUser.map(User::getPhone).map(Optional::get).orElseGet(() -> {
    // do something here
    return -1L;
});
orElseThrow(Supplier<? extends X> expectionSupplier)
登入後複製

与get()方法类似,都是在不满足条件时返回异常,不过这里我们可以指定返回的异常类型。

ifPresent(Consumer)

当满足条件时执行传入的参数化操作。

三. 注意事项

Optional是一个final类,未实现任何接口,所以当我们在利用该类包装定义类的属性的时候,如果我们定义的类有序列化的需求,那么因为Optional没有实现Serializable接口,这个时候执行序列化操作就会有问题:

public class User implements Serializable{
    /** 用户编号 */
    private long id;
    private String name;
    private int age;
    private Optional phone;  // 不能序列化
    private Optional<String> email;  // 不能序列化
登入後複製

不过我们可以采用如下替换策略:

private long phone;
public Optional<Long> getPhone() {
    return Optional.ofNullable(this.phone);
}
登入後複製

看来Optional在设计的时候就没有考虑将它作为类的字段使用~

 以上就是Java8 新特性之 Optional 类 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1673
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
Java 8中如何計算一年前或一年後的日期? Java 8中如何計算一年前或一年後的日期? Apr 26, 2023 am 09:22 AM

Java8計算一年前或一年後的日期利用minus()方法計算一年前的日期packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

Java 8中的Optional類別:如何使用orElseThrow()方法處理可能為空的值 Java 8中的Optional類別:如何使用orElseThrow()方法處理可能為空的值 Jul 30, 2023 pm 01:57 PM

Java8中的Optional類別:如何使用orElseThrow()方法處理可能為空的值引言:在Java開發中,我們經常會遇到處理可能為空的值的情況。在早期的Java版本中,我們通常會使用null來表示一個值的缺失。然而,使用null存在一些問題,例如我們需要頻繁判斷是否為null,容易出現空指標異常等。為了解決這些問題,Java8引入

PHP 8.3發布:新功能一覽 PHP 8.3發布:新功能一覽 Nov 27, 2023 pm 12:52 PM

PHP8.3發布:新功能一覽隨著技術的不斷發展和需求的不斷變化,程式語言也不斷更新和改進。作為一種廣泛應用於網頁開發的腳本語言,PHP一直在不斷進步,為開發者提供更強大和高效的工具。最近發布的PHP8.3版本帶來了許多期待已久的新功能和改進,以下讓我們來看看這些新特性的一覽。非空屬性的初始化在過去的PHP版本中,如果一個類別的屬性沒有明確賦值,它的值

學習PHP8的新特性,深入理解最新技術的指南 學習PHP8的新特性,深入理解最新技術的指南 Dec 23, 2023 pm 01:16 PM

深入解析PHP8的新特性,幫助您掌握最新技術隨著時間的推移,PHP程式語言一直在不斷演進和改進。最近發布的PHP8版本為開發者提供了許多令人興奮的新功能和改進,為我們的開發工作帶來了更多便利和效率。在本文中,我們將深入解析PHP8的新特性,並提供具體的程式碼範例,旨在幫助您更好地掌握這些最新的技術。 JIT編譯器PHP8引進了JIT(Just-In-Time)編

如何使用Java 8計算一週後的日期? 如何使用Java 8計算一週後的日期? Apr 21, 2023 pm 11:01 PM

Java8如何計算一週後的日期這個例子會計算一週後的日期。 LocalDate日期不包含時間訊息,它的plus()方法用來增加天、週、月,ChronoUnit類別宣告了這些時間單位。由於LocalDate也是不變型,回傳後一定要用變數賦值。 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

Java 8中的Optional類別:如何使用flatMap()方法處理多層巢狀的可能為空的值 Java 8中的Optional類別:如何使用flatMap()方法處理多層巢狀的可能為空的值 Jul 31, 2023 pm 10:33 PM

Java8中的Optional類別:如何使用flatMap()方法處理多層巢狀的可能為空的值引言:在軟體開發中,我們經常會遇到處理可能為空的值的情況。以前,我們可能會使用if-else語句來檢查物件是否為空,但這種方式顯得冗長且容易出錯。 Java8引入了Optional類,它是一個容器對象,可以包含可選的非null值。使用Optional類可以更簡潔安

php8有什麼新特性 php8有什麼新特性 Sep 25, 2023 pm 01:34 PM

php8新特性有JIT 編譯器、型別推導、命名參數、聯合型別、屬性、錯誤處理改進、非同步程式支援、新的標準函式庫函數和匿名類的擴充等。詳細介紹:1、JIT編譯器,PHP8引入了JIT編譯器,這是一個重要的效能改進,JIT編譯器可以對一些高頻執行的程式碼進行即時編譯和最佳化,從而提高運行速度;2、類型推導,PHP8引入了類型推導功能,允許開發者在宣告變數時自動推導出變數的類型等等。

Go語言新功能解讀:讓程式設計更有效率 Go語言新功能解讀:讓程式設計更有效率 Mar 10, 2024 pm 12:27 PM

【Go語言新特性解讀:讓程式設計更有效率,需要具體程式碼範例】近年來,Go語言在軟體開發領域備受關注,其簡潔、高效的設計理念吸引了越來越多的開發者。作為一種靜態類型的程式語言,Go語言不斷推出新的功能以提高開發效率,簡化程式碼編寫過程。本文將深入解讀Go語言最新的特性,探討如何透過具體的程式碼範例來體驗這些新特性帶來的便利性。模組化開發(GoModules)Go語言從1

See all articles