Java之Optional類判空使用及說明
簡(jiǎn)介
Optional是一個(gè)容器對(duì)象,它可能包含某個(gè)值,也可能不包含,它的設(shè)計(jì)目的是為了解決空指針異常問題。
使用Optional可以避免在代碼中顯式地檢查null值。
不過這個(gè)類有好有壞,適當(dāng)使用即可,其缺點(diǎn)就是造成代碼過于冗長(zhǎng),最主要是引入額外的對(duì)象開銷。
常見的Optional用法
現(xiàn)有一個(gè)實(shí)體類UserVo,該類有兩個(gè)屬性username、password,下述示例以該實(shí)體類測(cè)試。
創(chuàng)建Optional對(duì)象
of()方法
創(chuàng)建一個(gè)包含指定非null值的Optional對(duì)象
public class OptionalTest {
public static void main(String[] args) {
UserVo userVo = new UserVo();
userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.of(userVo.getUsername());
if (usernameOptional.isPresent()) {
System.err.println("獲取的信息為 " + usernameOptional.get());
} else {
System.err.println("usernameOptional為空");
}
}
}
// 執(zhí)行結(jié)果
獲取的信息為 張三
使用of()方法創(chuàng)建了一個(gè)包含非null值的Optional對(duì)象。然后我們通過調(diào)用isPresent()方法檢查Optional是否包含值。
如果Optional包含值,則調(diào)用get()方法獲取該值并打印輸出;否則打印輸出Optional為空。
使用of()方法時(shí),如果傳入的值為null,會(huì)立即拋出NullPointerException異常。因此,在使用of()方法創(chuàng)建Optional對(duì)象時(shí),需要確保傳入的值不為空。
如果值可能為空,可以使用ofNullable()方法創(chuàng)建Optional對(duì)象,該方法可以接受null值。
ofNullable()方法
創(chuàng)建一個(gè)包含指定值的Optional對(duì)象,如果值為null,則創(chuàng)建一個(gè)空的Optional對(duì)象。
public class OptionalTest {
public static void main(String[] args) {
UserVo userVo = new UserVo();
// userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
if (usernameOptional.isPresent()) {
System.err.println("獲取的信息為 " + usernameOptional.get());
} else {
System.err.println("usernameOptional為空");
}
}
}
// 執(zhí)行結(jié)果
usernameOptional為空
使用ofNullable()方法創(chuàng)建了一個(gè)包含指定值的Optional對(duì)象。如果值為null,則創(chuàng)建一個(gè)空的Optional對(duì)象。然后我們通過調(diào)用isPresent()方法檢查Optional是否包含值。如果Optional包含值,則調(diào)用get()方法獲取該值并打印輸出;否則打印輸出Optional為空。
使用ofNullable()方法創(chuàng)建的Optional對(duì)象可以接受null值,不會(huì)立即拋出NullPointerException異常。這樣可以更靈活地處理可能為空的值。
empty()方法
創(chuàng)建一個(gè)空的Optional對(duì)象。
public class OptionalTest {
public static void main(String[] args) {
Optional<String> usernameOptional = Optional.empty();
if (usernameOptional.isPresent()) {
System.err.println("獲取的信息為 " + usernameOptional.get());
} else {
System.err.println("usernameOptional 為空");
}
}
}
// 執(zhí)行結(jié)果
usernameOptional為空
使用empty()方法創(chuàng)建了一個(gè)空的Optional對(duì)象。然后我們通過調(diào)用isPresent()方法檢查Optional是否包含值。
由于我們使用empty()方法創(chuàng)建的Optional對(duì)象是空的,所以isPresent()返回值為false,程序會(huì)打印輸出Optional為空,使用empty()方法創(chuàng)建的Optional對(duì)象始終是空的,不包含任何值,這在某些情況下可以用于表示缺失值。
判斷Optional是否包含值
isPresent()方法
如果Optional對(duì)象包含值,則返回true,否則返回false,上述示例判斷部分已經(jīng)用到
ifPresent()方法
如果Optional對(duì)象不為空則執(zhí)行ifPresent()中的處理邏輯,否則不予執(zhí)行。
public class OptionalTest {
public static void main(String[] args) throws Throwable {
UserVo userVo = new UserVo();
userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
usernameOptional.ifPresent(new Consumer<String>() {
@Override
public void accept(String s) {
System.err.println("業(yè)務(wù)邏輯處理");
}
});
}
}
當(dāng)userVo正常給userName賦值時(shí)
輸出結(jié)果:業(yè)務(wù)邏輯處理
沒有賦值時(shí),不輸出任何結(jié)果
獲取Optional中的值
get()方法
如果Optional對(duì)象包含值,則返回該值,否則拋出NoSuchElementException異常,上述示例判斷部分已經(jīng)用到
注意,使用get()方法時(shí),一定要先使用isPresent()方法來檢查Optional對(duì)象是否包含值,以避免拋出異常
filter()方法
用于過濾 Optional 對(duì)象中的值,只有當(dāng)值滿足特定條件時(shí)才保留
public class OptionalTest {
public static void main(String[] args) throws Throwable {
UserVo userVo = new UserVo();
userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
Optional<String> optional = usernameOptional.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length() == 2;
}
});
System.err.println(optional.get());
}
}
上述過濾條件為字符串的長(zhǎng)度是否為2,是的話取出值
輸出結(jié)果:張三
但當(dāng)長(zhǎng)度判斷不是等于2時(shí),過濾后沒有符合條件的數(shù)據(jù),會(huì)拋出NoSuchElementException異常。
orElse()方法
如果Optional對(duì)象包含值,則返回該值,否則返回指定的默認(rèn)值。
public class OptionalTest {
public static void main(String[] args) {
UserVo userVo = new UserVo();
userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.of(userVo.getUsername());
// Optional<String> usernameOptional = Optional.empty();
String string = usernameOptional.orElse("李四");
System.err.println(string);
}
}
使用of()方法創(chuàng)建一個(gè)非空的Optional對(duì)象,并將賦值后的userName作為值傳遞給它。然后,我們使用orElse()方法獲取Optional對(duì)象的值,如果Optional對(duì)象為空,則返回指定的默認(rèn)值"李四"。
當(dāng)示例中調(diào)用的是of()方法時(shí)
輸出結(jié)果:張三
當(dāng)示例中調(diào)用的是empty()方法時(shí)
輸出結(jié)果:李四
orElseGet()方法
如果Optional對(duì)象包含值,則返回該值,否則通過調(diào)用Supplier接口提供的方法來生成一個(gè)默認(rèn)值。
public class OptionalTest {
public static void main(String[] args) {
UserVo userVo = new UserVo();
// userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
String string = usernameOptional.orElseGet(new Supplier<String>() {
@Override
public String get() {
return "李四";
}
});
System.out.println(string);
}
}
使用ofNullable()方法創(chuàng)建了一個(gè)包含指定值的Optional對(duì)象。如果值為null,則創(chuàng)建一個(gè)空的Optional對(duì)象。然后調(diào)用了orElseGet()方法。
運(yùn)行測(cè)試,當(dāng)userVo正常給userName賦值時(shí)
輸出結(jié)果:張三
沒有賦值時(shí)
輸出結(jié)果:李四
orElseThrow()方法
如果Optional對(duì)象包含值,則返回該值,否則通過調(diào)用Supplier接口提供的方法來拋出指定的異常。
public class OptionalTest {
public static void main(String[] args) throws Throwable {
UserVo userVo = new UserVo();
// userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
String string = usernameOptional.orElseThrow(new Supplier<Throwable>() {
@Override
public Throwable get() {
throw new RuntimeException("拋出指定異常");
}
});
System.err.println(string);
}
}
當(dāng)userVo正常給userName賦值時(shí)
輸出結(jié)果:張三
沒有賦值時(shí)
Exception in thread "main" java.lang.RuntimeException: 拋出指定異常
at com.sun.test.OptionalTest$1.get(OptionalTest.java:16)
at com.sun.test.OptionalTest$1.get(OptionalTest.java:13)
at java.util.Optional.orElseThrow(Optional.java:290)
at com.sun.test.OptionalTest.main(OptionalTest.java:13)?
轉(zhuǎn)換Optional中的值
map()方法
對(duì)Optional中的值進(jìn)行轉(zhuǎn)換,并返回一個(gè)新的Optional對(duì)象。
public class OptionalTest {
public static void main(String[] args) throws Throwable {
UserVo userVo = new UserVo();
userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
Optional<String> optional = usernameOptional.map(new Function<String, String>() {
@Override
public String apply(String s) {
return s + " -- 值轉(zhuǎn)換";
}
});
System.err.println(optional.get());
}
}
創(chuàng)建一個(gè)包含指定值的Optional對(duì)象,如果值為null,則創(chuàng)建一個(gè)空的Optional對(duì)象,userVo.getUsername()不為空,走后續(xù)邏輯,調(diào)用map()方法,生成新的Optional對(duì)象,最后用get()方法獲取Optional中的值。
輸出結(jié)果:張三 -- 值轉(zhuǎn)換
flatMap()方法
對(duì)Optional中的值進(jìn)行轉(zhuǎn)換,并返回一個(gè)新的Optional對(duì)象。
public class OptionalTest {
public static void main(String[] args) throws Throwable {
UserVo userVo = new UserVo();
userVo.setUsername("張三");
Optional<String> usernameOptional = Optional.ofNullable(userVo.getUsername());
Optional<String> optional = usernameOptional.flatMap(new Function<String, Optional<String>>() {
@Override
public Optional<String> apply(String s) {
return Optional.ofNullable(s + " -- 值轉(zhuǎn)換");
}
});
System.err.println(optional.get());
}
}
輸出結(jié)果:張三 -- 值轉(zhuǎn)換
輸出結(jié)果與調(diào)用map()一樣,且該方法處理邏輯稍復(fù)雜一些,map()和flatMap()按需選擇即可。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
spring?boot前后端交互之?dāng)?shù)據(jù)格式轉(zhuǎn)換問題
這篇文章主要介紹了spring?boot前后端交互之?dāng)?shù)據(jù)格式轉(zhuǎn)換,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01
Java Selenium實(shí)現(xiàn)多窗口切換的示例代碼
這篇文章主要介紹了Java Selenium實(shí)現(xiàn)多窗口切換的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Java確保MQ消息隊(duì)列不丟失的實(shí)現(xiàn)與流程分析
在分布式系統(tǒng)中,消息隊(duì)列是核心組件之一,本文將探討如何確保MQ消息隊(duì)列不丟失,并通過Java代碼示例和流程圖來演示解決方案,需要的可以了解下2025-05-05
idea解決程序包不存在報(bào)錯(cuò)的八種解決方法
這篇文章主要介紹了idea解決程序包不存在報(bào)錯(cuò)的八種解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-02-02
Mybatis-plus通過添加攔截器實(shí)現(xiàn)簡(jiǎn)單數(shù)據(jù)權(quán)限
系統(tǒng)需要根據(jù)用戶所屬的公司,來做一下數(shù)據(jù)權(quán)限控制,具體一點(diǎn),就是通過表中的company_id進(jìn)行權(quán)限控制,項(xiàng)目使用的是mybatis-plus,所以通過添加攔截器的方式,修改查詢sql,實(shí)現(xiàn)數(shù)據(jù)權(quán)限,本文就通過代碼給大家詳細(xì)的講解一下,需要的朋友可以參考下2023-08-08
SpringBoot讀取Resource目錄文件的五種常見方式
在Spring Boot開發(fā)中,我們經(jīng)常需要讀取src/main/resources目錄下的文件,src/main/resources 目錄下通常存放配置文件、模板、靜態(tài)資源、SQL腳本等,本文給大家介紹了SpringBoot讀取Resource目錄文件的五種常見方式,需要的朋友可以參考下2025-07-07

