Java8?Optional常用方法使用場景分析
前言
Optional 是 Java 8 的新特性,專治空指針異常(NullPointerException, 簡稱 NPE)問題,它是一個容器類,里面只存儲一個元素(這點不同于 Conllection)。
為方便用戶通過 Lambda 表達(dá)式調(diào)用 Optional 的方法,部分方法(如:filter、ifPresent、map、orElseGet)需傳入函數(shù)式接口(如:Predicate、Consumer、Function、Supplier)參數(shù)。
項目場景:
業(yè)務(wù)需求是這樣的,從第三方拉取用戶信息,然后保存到公司自己的數(shù)據(jù)庫,而第三方接口返回的數(shù)據(jù)是 JSON 格式的,需要獲取到用戶地址相關(guān)信息,但是用戶地址相關(guān)信息卻藏的十分深,如下面所示,JSON 節(jié)點是這樣的:
{"userInfo":{"userDetails":{"city":"深圳市"}}}基本實現(xiàn)
創(chuàng)建相關(guān)實體用來接收
import lombok.Data;
@Data
public class User {
private Integer id; // id
private UserInfo userInfo; // 用戶信息
public User(UserInfo userInfo) {
this.userInfo = userInfo;
}
}import lombok.Data;
@Data
public class UserInfo {
private String userName; // 用戶名稱
private UserDetails userDetails; // 用戶詳情
public UserInfo(UserDetails userDetails) {
this.userDetails = userDetails;
}
}import lombok.Data;
@Data
public class UserDetails {
private String address; // 住址
private String city; // 城市
public UserDetails(String city) {
this.city = city;
}
}示例代碼
1.常用的寫法
- 缺點:if嵌套非常深
import com.test.entity.User;
import com.test.entity.UserDetails;
import com.test.entity.UserInfo;
import java.util.Optional;
public class TestService {
public static void main(String[] args) {
UserDetails userDetails = new UserDetails("深圳市");
UserInfo userInfo = new UserInfo(userDetails);
User user = new User(userInfo);
System.out.println(getCity(user));
}
/**
* 以前的寫法
* @param user 用戶對象
* @return 用戶所在城市
*/
public static String getCity(User user){
if(user != null){
UserInfo userInfo = user.getUserInfo();
if(userInfo != null){
UserDetails userDetails = userInfo.getUserDetails();
if(userDetails != null){
return userDetails.getCity();
}
}
}
return null;
}
}2.JAVA8寫法
- 優(yōu)點:不用再額外判斷空指針
import com.test.entity.User;
import com.test.entity.UserDetails;
import com.test.entity.UserInfo;
import java.util.Optional;
public class TestService {
public static void main(String[] args) {
UserDetails userDetails = new UserDetails("深圳市");
UserInfo userInfo = new UserInfo(userDetails);
User user = new User(userInfo);
System.out.println(getCity_java8(user));
}
/**
* java8寫法
* @param user 用戶對象
* @return 用戶所在城市
*/
public static String getCity_java8(User user){
return Optional.ofNullable(user)
.map(u -> u.getUserInfo())
.map(d -> d.getUserDetails())
.map(t -> t.getCity())
.orElse(null);
}
}源碼解析
為什么Optional不用判斷空指針了呢,其實這并沒有用什么高超的技術(shù),看源碼可以發(fā)現(xiàn)其實是它已經(jīng)幫我們處理好了
1.映射元素(map)
//將 T 類型元素映射為 U 類型元素
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}2.創(chuàng)建容器(ofNullable)
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}3.容器判空(isPresent)
// 判斷 Optional Value 有沒有值
public boolean isPresent() {
return value != null;
}總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java基礎(chǔ)之 “==”與“equals”區(qū)別詳解
這篇文章主要介紹了java基礎(chǔ)之 “==”與“equals”區(qū)別詳解,需要的朋友可以參考下2020-02-02
Java使用Arrays.asList報UnsupportedOperationException的解決
這篇文章主要介紹了Java使用Arrays.asList報UnsupportedOperationException的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
關(guān)于Idea中的.properties文件顯示問題
這篇文章主要介紹了關(guān)于Idea中的.properties文件顯示問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
解決redisTemplate向redis中插入String類型數(shù)據(jù)時出現(xiàn)亂碼問題
這篇文章主要介紹了解決redisTemplate向redis中插入String類型數(shù)據(jù)時出現(xiàn)亂碼問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
如何利用Spring?MVC實現(xiàn)RESTful風(fēng)格
這篇文章主要介紹了如何利用Spring?MVC實現(xiàn)RESTful風(fēng)格,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
Spring中的ApplicationContext與BeanFactory詳解
這篇文章主要介紹了Spring中的ApplicationContext與BeanFactory詳解,Spring的IoC容器就是一個實現(xiàn)了BeanFactory接口的可實例化類,事實上, Spring提供了兩種不同的容器,一種是最基本的BeanFactory,另一種是擴(kuò)展的ApplicationContext,需要的朋友可以參考下2024-01-01

