Java 8 Optional類深度解析

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

身為一名Java程序員,大家可能都有這樣的經歷:調用一個方法得到了返回值卻不能直接將返回值作為參數去調用別的方法。我們首先要判斷這個返回值是否為null,只有在非空的前提下才能將其作為其他方法的參數。這正是一些類似Guava的外部API試圖解決的問題。一些JVM編程語言比如Scala、Ceylon等已經將對在核心API中解決了這個問題。在我的前一篇文章中,介紹了Scala是如何解決了這個問題。

新版本的Java,比如Java 8引入了一個新的Optional類。Optional類的Javadoc描述如下:

這是一個可以為null的容器對象。如果值存在則isPresent()方法會返回true,調用get()方法會返回該對象。

本文會逐個探討Optional類包含的方法,并通過一兩個示例展示如何使用。

1、of

為非null的值創建一個Optional。

of方法通過工廠方法創建Optional類。需要注意的是,創建對象時傳入的參數不能為null。如果傳入參數為null,則拋出NullPointerException 。

//調用工廠方法創建Optional實例
Optional<String> name = Optional.of("Sanaulla");
//傳入參數為null,拋出NullPointerException.
Optional<String> someNull = Optional.of(null);

2、ofNullable

為指定的值創建一個Optional,如果指定的值為null,則返回一個空的Optional。

ofNullable與of方法相似,唯一的區別是可以接受參數為null的情況。示例如下:

//下面創建了一個不包含任何值的Optional實例
//例如,值為'null'
Optional empty = Optional.ofNullable(null);

3、isPresent

非常容易理解

如果值存在返回true,否則返回false。

類似下面的代碼:

//isPresent方法用來檢查Optional實例中是否包含值
if (name.isPresent()) {//在Optional實例內調用get()返回已存在的值System.out.println(name.get());//輸出Sanaulla
}

4、get

如果Optional有值則將其返回,否則拋出NoSuchElementException。

上面的示例中,get方法用來得到Optional實例中的值。下面我們看一個拋出NoSuchElementException的例子:

//執行下面的代碼會輸出:No value present 
try {//在空的Optional實例上調用get(),拋出NoSuchElementExceptionSystem.out.println(empty.get());
} catch (NoSuchElementException ex) {System.out.println(ex.getMessage());
}

5、ifPresent

如果Optional實例有值則為其調用consumer,否則不做處理

要理解ifPresent方法,首先需要了解Consumer類。簡答地說,Consumer類包含一個抽象方法。該抽象方法對傳入的值進行處理,但沒有返回值。Java8支持不用接口直接通過lambda表達式傳入參數。

如果Optional實例有值,調用ifPresent()可以接受接口段或lambda表達式。類似下面的代碼:

//ifPresent方法接受lambda表達式作為參數。
//lambda表達式對Optional的值調用consumer進行處理。
name.ifPresent((value) -> {System.out.println("The length of the value is: " + value.length());
});

6、orElse

如果有值則將其返回,否則返回指定的其它值。

如果Optional實例有值則將其返回,否則返回orElse方法傳入的參數。示例如下:

//如果值不為null,orElse方法返回Optional實例的值。
//如果為null,返回傳入的消息。
//輸出:There is no value present!
System.out.println(empty.orElse("There is no value present!"));
//輸出:Sanaulla
System.out.println(name.orElse("There is some value!"));

7、orElseGet

orElseGet與orElse方法類似,區別在于得到的默認值。orElse方法將傳入的字符串作為默認值,orElseGet方法可以接受Supplier接口的實現用來生成默認值。示例如下:

//orElseGet與orElse方法類似,區別在于orElse傳入的是默認值,
//orElseGet可以接受一個lambda表達式生成默認值。
//輸出:Default Value
System.out.println(empty.orElseGet(() -> "Default Value"));
//輸出:Sanaulla
System.out.println(name.orElseGet(() -> "Default Value"));

8、orElseThrow

如果有值則將其返回,否則拋出supplier接口創建的異常。

在orElseGet方法中,我們傳入一個Supplier接口。然而,在orElseThrow中我們可以傳入一個lambda表達式或方法,如果值不存在來拋出異常。示例如下:

try {//orElseThrow與orElse方法類似。與返回默認值不同,//orElseThrow會拋出lambda表達式或方法生成的異常 empty.orElseThrow(ValueAbsentException::new);
} catch (Throwable ex) {//輸出: No value present in the Optional instanceSystem.out.println(ex.getMessage());
}

ValueAbsentException定義如下:

class ValueAbsentException extends Throwable {public ValueAbsentException() {super();}public ValueAbsentException(String msg) {super(msg);}@Overridepublic String getMessage() {return "No value present in the Optional instance";}
}

9、map

map方法文檔說明如下:

如果有值,則對其執行調用mapping函數得到返回值。如果返回值不為null,則創建包含mapping返回值的Optional作為map方法返回值,否則返回空Optional。

map方法用來對Optional實例的值執行一系列操作。通過一組實現了Function接口的lambda表達式傳入操作。如果你不熟悉Function接口,可以參考我的這篇博客。map方法示例如下:

//map方法執行傳入的lambda表達式參數對Optional實例的值進行修改。
//為lambda表達式的返回值創建新的Optional實例作為map方法的返回值。
Optional<String> upperName = name.map((value) -> value.toUpperCase());
System.out.println(upperName.orElse("No value found"));

10、flatMap

如果有值,為其執行mapping函數返回Optional類型返回值,否則返回空Optional。flatMap與map(Funtion)方法類似,區別在于flatMap中的mapper返回值必須是Optional。調用結束時,flatMap不會對結果用Optional封裝。

flatMap方法與map方法類似,區別在于mapping函數的返回值不同。map方法的mapping函數返回值可以是任何類型T,而flatMap方法的mapping函數必須是Optional。

參照map函數,使用flatMap重寫的示例如下:

//flatMap與map(Function)非常類似,區別在于傳入方法的lambda表達式的返回類型。
//map方法中的lambda表達式返回值可以是任意類型,在map函數返回之前會包裝為Optional。 
//但flatMap方法中的lambda表達式返回值必須是Optionl實例。 
upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));
System.out.println(upperName.orElse("No value found"));//輸出SANAULLA

11、filter

filter個方法通過傳入限定條件對Optional實例的值進行過濾。文檔描述如下:

如果有值并且滿足斷言條件返回包含該值的Optional,否則返回空Optional。

讀到這里,可能你已經知道如何為filter方法傳入一段代碼。是的,這里可以傳入一個lambda表達式。對于filter函數我們應該傳入實現了Predicate接口的lambda表達式。如果你不熟悉Predicate接口,可以參考這篇文章。

現在我來看看filter的各種用法,下面的示例介紹了滿足限定條件和不滿足兩種情況:

//filter方法檢查給定的Option值是否滿足某些條件。
//如果滿足則返回同一個Option實例,否則返回空Optional。
Optional<String> longName = name.filter((value) -> value.length() > 6);
System.out.println(longName.orElse("The name is less than 6 characters"));//輸出Sanaulla//另一個例子是Optional值不滿足filter指定的條件。
Optional<String> anotherName = Optional.of("Sana");
Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);
//輸出:name長度不足6字符
System.out.println(shortName.orElse("The name is less than 6 characters"));

以上,我們介紹了Optional類的各個方法。下面通過一個完整的示例對用法集中展示:

public class OptionalDemo {public static void main(String[] args) {//創建Optional實例,也可以通過方法返回值得到。Optional<String> name = Optional.of("Sanaulla");//創建沒有值的Optional實例,例如值為'null'Optional empty = Optional.ofNullable(null);//isPresent方法用來檢查Optional實例是否有值。if (name.isPresent()) {//調用get()返回Optional值。System.out.println(name.get());}try {//在Optional實例上調用get()拋出NoSuchElementException。System.out.println(empty.get());} catch (NoSuchElementException ex) {System.out.println(ex.getMessage());}//ifPresent方法接受lambda表達式參數。//如果Optional值不為空,lambda表達式會處理并在其上執行操作。name.ifPresent((value) -> {System.out.println("The length of the value is: " + value.length());});//如果有值orElse方法會返回Optional實例,否則返回傳入的錯誤信息。System.out.println(empty.orElse("There is no value present!"));System.out.println(name.orElse("There is some value!"));//orElseGet與orElse類似,區別在于傳入的默認值。//orElseGet接受lambda表達式生成默認值。System.out.println(empty.orElseGet(() -> "Default Value"));System.out.println(name.orElseGet(() -> "Default Value"));try {//orElseThrow與orElse方法類似,區別在于返回值。//orElseThrow拋出由傳入的lambda表達式/方法生成異常。empty.orElseThrow(ValueAbsentException::new);} catch (Throwable ex) {System.out.println(ex.getMessage());}//map方法通過傳入的lambda表達式修改Optonal實例默認值。 //lambda表達式返回值會包裝為Optional實例。Optional<String> upperName = name.map((value) -> value.toUpperCase());System.out.println(upperName.orElse("No value found"));//flatMap與map(Funtion)非常相似,區別在于lambda表達式的返回值。//map方法的lambda表達式返回值可以是任何類型,但是返回值會包裝成Optional實例。//但是flatMap方法的lambda返回值總是Optional類型。upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));System.out.println(upperName.orElse("No value found"));//filter方法檢查Optiona值是否滿足給定條件。//如果滿足返回Optional實例值,否則返回空Optional。Optional<String> longName = name.filter((value) -> value.length() > 6);System.out.println(longName.orElse("The name is less than 6 characters"));//另一個示例,Optional值不滿足給定條件。Optional<String> anotherName = Optional.of("Sana");Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);System.out.println(shortName.orElse("The name is less than 6 characters"));}}

上述代碼輸出如下:

Sanaulla
No value present
The length of the value is: 8
There is no value present!
Sanaulla
Default Value
Sanaulla
No value present in the Optional instance
SANAULLA
SANAULLA
Sanaulla
The name is less than 6 characters

轉載于:https://my.oschina.net/u/3136594/blog/1585708

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/392025.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/392025.shtml
英文地址,請注明出處:http://en.pswp.cn/news/392025.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鴿子 迷信_人工智能如何幫助我戰勝鴿子

鴿子 迷信鴿子回避系統 (Pigeon Avoidance System) Disclaimer: You are reading Part 1 that gives an overview of the project. Part 2 describes the technical setup and data collection. Part 3 is about how to train the Pigeon Recognition Model and run it on Rasp…

華為鴻蒙會議安排,2020華為HDC日程確定,鴻蒙、HMS以及EMUI 11成最關注點

原標題&#xff1a;2020華為HDC日程確定&#xff0c;鴻蒙、HMS以及EMUI 11成最關注點HDC&#xff1a;華為開發者大會&#xff0c;目前已經確定將在9月10日正式開幕。日前華為已經在其官網公布了HDC的日程&#xff0c;從現在的消息看華為開發者大會有三大點最受業內關注。鴻蒙操…

反射、元類

一、反射 1、什么是反射&#xff1a;就是反省&#xff0c;自省的意思 反射指的是一個對象應該具備&#xff0c;可以增、刪、改、查屬性的能力&#xff0c;通過字符串來操作屬性 涉及的四個函數&#xff0c;這四個函數就是普通的內置函數&#xff0c;只是沒有下劃線而已&#xf…

Java—簡單的圖書管理系統

簡單的圖書管理系統 通過數據源和DAO對象訪問數據庫。其中JavaBeans實現模型&#xff0c;訪問數據庫&#xff0c;Servlet實現控制器&#xff0c;JSP頁面實現視圖。 ? 模型包括2個JavaBean&#xff1a;BookBean用于存放圖書信息&#xff0c;BookDAO用于訪問數據庫。 ? 控制器包…

成功的秘訣是什么_學習編碼的10個成功秘訣

成功的秘訣是什么This post was originally published on Coder-Coder.com.該帖子最初發布在Coder-Coder.com上 。 If you’re teaching yourself how to code, you may have more questions than answers when you’re starting out.如果您正在教自己如何編碼&#xff0c;那么…

ZJUT 地下迷宮 (高斯求期望)

http://cpp.zjut.edu.cn/ShowProblem.aspx?ShowID1423 設dp[i]表示在i點時到達終點要走的期望步數&#xff0c;那么dp[i] ∑1/m*dp[j] 1&#xff0c;j是與i相連的點&#xff0c;m是與i相鄰的點數。建立方程組求解。重要的一點是先推斷DK到達不了的點。須要bfs預處理一下進行…

html收款頁面模板,訂單收款.html

&#xfeff;訂單收款$axure.utils.getTransparentGifPath function() { return resources/images/transparent.gif; };$axure.utils.getOtherPath function() { return resources/Other.html; };$axure.utils.getReloadPath function() { return resources/reload.html; };…

pandas之時間數據

1.時間戳Timestamp() 參數可以為各種形式的時間&#xff0c;Timestamp()會將其轉換為時間。 time1 pd.Timestamp(2019/7/13) time2 pd.Timestamp(13/7/2019 13:05) time3 - pd.Timestamp(2019-7-13) time4 pd.Timestamp(2019 7 13 13:05) time5 pd.Timestamp(2019 July 13 …

scikit keras_Scikit學習,TensorFlow,PyTorch,Keras…但是天秤座呢?

scikit kerasWelcome all! In the first episode of this series, I investigated the four most known machine learning frameworks and discussed which of these you should learn depending on your needs and goals.w ^迎閱讀所有&#xff01; 在本系列的第一集中 &#…

程序員如何學習更好的知識_如何保持學習并成為更好的程序員

程序員如何學習更好的知識by Kevin Gardner凱文加德納(Kevin Gardner) 如何保持學習并成為更好的程序員 (How to keep learning and become a better coder) Coding has come a long way since the days of Robert Taylor and ARPANET and Sir Tim Berners-Lee and CERN — an…

Educational Codeforces Round 25 C. Multi-judge Solving

題目鏈接&#xff1a;http://codeforces.com/contest/825/problem/C C. Multi-judge Solving time limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputMakes solves problems on Decoforces and lots of other different onli…

Java—stream以及集合框架使用

1) 編寫Student類&#xff0c;主要屬性包括學號、姓名、性別、班級 2) 編寫Score類&#xff0c;主要屬性包括&#xff1a;學號、課程名、分數 3) 模擬期末考試的成績統計應用場景&#xff0c;要求 (1) 所有學生名單及對應科目成績已經初始化在數組中 (2) 要求輸出每門課程的所有…

山東省2021年高考成績查詢平臺6,山東2021年高考成績改為6月26日前公布

6月11日&#xff0c;山東省教育廳舉行2021年第一次高考新聞發布會&#xff0c;介紹2021年高考基本情況、評卷安排、成績公布等相關工作。山東省教育招生考試院新聞發言人、普招處處長李春光介紹&#xff0c;根據近期國家有關工作要求和強基計劃招生工作需要&#xff0c;原定于6…

如何在vuejs里禁用eslint語法檢查工具

eslint好是好&#xff0c;可要求很苛刻&#xff0c;對于我這種寫代碼很糙的媛。。。。。。 搜索的時候有的說加入 /* eslint-disabled */&#xff08;有用&#xff0c;但只是部分代碼享受此待遇&#xff09; 還有說刪除.eslintrc.js里包含eslint關鍵字的塊&#xff0c;a---o---…

數據結構兩個月學完_這是我作為數據科學家兩年來所學到的

數據結構兩個月學完It has been 2 years ever since I started my data science journey. Boy, that was one heck of a roller coaster ride!自從我開始數據科學之旅以來已經有兩年了 。 男孩 &#xff0c;那可真是坐過山車&#xff01; There were many highs and lows, and…

leetcode 888. 公平的糖果棒交換(set)

愛麗絲和鮑勃有不同大小的糖果棒&#xff1a;A[i] 是愛麗絲擁有的第 i 根糖果棒的大小&#xff0c;B[j] 是鮑勃擁有的第 j 根糖果棒的大小。 因為他們是朋友&#xff0c;所以他們想交換一根糖果棒&#xff0c;這樣交換后&#xff0c;他們都有相同的糖果總量。&#xff08;一個…

如何使用JavaScript檢查輸入是否為空

by Zell Liew由Zell Liew 如何使用JavaScript檢查輸入是否為空 (How to check if an input is empty with JavaScript) Last week, I shared how to check if an input is empty with CSS. Today, let’s talk about the same thing, but with JavaScript.上周&#xff0c;我分…

數學哲學與科學哲學和計算機科學的能動作用,數學哲學與科學哲學和計算機科學的能動作用...

3 數學哲學與計算機科學的能動作用數學哲學對于計算機科學的影響主要表現于以下的事實&#xff1a;一些源于數學哲學(數學基礎研究)的概念和理論在計算機科學的歷史發展中發揮了十分重要的作用。例如&#xff0c;在此可以首先提及(一階)謂詞演算理論&#xff1a;這是由弗雷格(…

AngularDart4.0 指南- 表單

2019獨角獸企業重金招聘Python工程師標準>>> 表單是商業應用程序的主流。您可以使用表單登錄&#xff0c;提交幫助請求&#xff0c;下訂單&#xff0c;預訂航班&#xff0c;安排會議&#xff0c;并執行無數其他數據錄入任務。 在開發表單時&#xff0c;創建一個數據…

(轉載)分享常用的GoLang包工具

分享常用的GoLang包工具 包名 鏈接地址 備注 Machinery異步隊列 https://github.com/RichardKnop/machinery Mqtt通信 github.com/eclipse/paho.mqtt.golang go文檔http://www.eclipse.org/paho/clients/golang/ 微信開發 https://github.com/chanxuehong/wechat fasthttp包 gi…