Java8?Optional常用方法使用場景分析
前言
Optional 是 Java 8 的新特性,專治空指針異常(NullPointerException, 簡稱 NPE)問題,它是一個容器類,里面只存儲一個元素(這點不同于 Conllection)。
為方便用戶通過 Lambda 表達式調(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)文章
Spring Cloud Feign內(nèi)部實現(xiàn)代碼細節(jié)
Feign 的英文表意為“假裝,偽裝,變形”, 是一個http請求調(diào)用的輕量級框架,可以以Java接口注解的方式調(diào)用Http請求,而不用像Java中通過封裝HTTP請求報文的方式直接調(diào)用。接下來通過本文給大家分享Spring Cloud Feign內(nèi)部實現(xiàn)代碼細節(jié),感興趣的朋友一起看看吧2021-05-05