java.util.Optional學習筆記
###三種Optional構造方法### 第一種. Optional.of(Object object):入參object不能為空,否則會丟擲空指標異常,檢視Optional原始碼發現會呼叫Objects.requireNonNull方法,裡面有判空:
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
第二種. Optional.ofNullable(Object object):入參object可以為空,如果object不為空,就建立一個Optional例項;如果object為空就返回一個static fainal的Option物件,注意這裡不會新建Option例項,而是使用一個static final的例項EMPTY,這裡比較有意思的是泛型的問題,例如我需要兩個Optional物件,型別分別是String和Integer,程式碼如下:
Optional<String> optionalStr = Optional.ofNullable(null);
Optional<Integer> optionalInt = Optional.ofNullable(null);
型別不同又如何保證返回同一個物件呢?直接看ofNullable的原始碼,發現會呼叫empty方法:
public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; }
原來是通過強制轉換實現的,再看EMPTY物件:
private static final Optional<?> EMPTY = new Optional<>();
是通過"?"宣告的;
第三種. Optional.empty():就是上面分析Optional.ofNullable的時候用到的empty方法,直接返回一個static final的例項EMPTY;
Optional.of()方法的用法有點像斷言,物件為空的時候代表著某種業務上不可接受的異常,需要儘早處理,並且業務拒絕執行,這種場景下可以使用Optional.of;
接下來我們開始實戰吧;
###例子中用到的物件:Student### Student是個普通的bean,有三個欄位和對應的get&set方法
package com.bolingcavalry;
/**
* @author willzhao
* @version V1.0
* @Description: 一個普通的bean
* @email [email protected]
* @Date 2017/8/26 下午11:23
*/
public class Student {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
}
###Optional.ofNullable的用法### 下面舉例說明最常用的Optional.ofNullable,我們打算根據名稱從其他系統獲取student物件,如果物件為空就返回預設物件,先看不用Optional的時候我們平常是怎麼寫的,如下程式碼所示,標準的if&else判斷:
private Student queryById(int id){
//TODO 這裡模擬從資料庫查詢
return null;
}
public Student getStudent(int id){
Student student = queryById(id));
//如果為空就返回DEFAULT物件
return student==null ? DEFAULT : student;
}
用Optional之後,如下所示,不需要通過判空來避免空指標異常了:
private Student queryById(int id){
//TODO 這裡模擬從資料庫查詢
return null;
}
public Student getStudent(int id){
Optional<Student> optional = Optional.ofNullable(queryById(id));
//如果為空就返回DEFAULT物件
return optional.orElse(DEFAULT);
}
orElse方法可以指定一個value為空時的返回物件,如果這個物件需要呼叫方法才能獲取(例如我們拿不到DEFAULT物件,要通過getDefault()方法才能拿到),這是就需要orElseGet方法來達到目的,如下:
private Student queryById(int id){
//TODO 這裡模擬從資料庫查詢
return null;
}
private Student getDefault(){
return DEFAULT;
}
public Student getStudent(int id){
Optional<Student> optional = Optional.ofNullable(queryById(id));
//如果為空就返回DEFAULT物件
return optional.orElseGet(() -> getDefault());
}
###Optional的map方法### 假如我們的需求是student物件非空就返回name的大寫,如果student物件為空就返回"invalid",在沒有Optional的時候寫法如下,除了檢查student變數是否為空,還要檢查name是否為空:
private Student queryById(int id){
//TODO 這裡模擬從資料庫查詢
return null;
}
public String getStudentUpperName(int id){
Student student = queryById(id);
if(student!=null && student.getName()!=null){
return student.getName().toUpperCase();
}
return "invalid";
}
用了Optional可以這麼寫:
private Student queryById(int id){
//TODO 這裡模擬從資料庫查詢
return null;
}
public String getStudentUpperName(int id){
Optional<Student> optional = Optional.ofNullable(queryById(id));
return optional.map(student -> student.getName())
.map(name -> name.toUpperCase())
.orElse("invalid");
}
由以上程式碼可以看到,map可以將一個Optional物件轉換成另一個,第一次是將Optional<Student>轉換成了Optional<String>,第二次是將Optional<String>轉成了另一個Optional<String>,只是這次將字串換成了大寫;
本次實戰的原始碼已經上傳到git上,地址是<font color="red">[email protected]:zq2599/blog_demos.git</font>,裡面有多個工程,本次用到的是optionaldemo,如下圖紅框所示:
以上就是Optional的基本用法,對Optional的使用是在習慣上對之前判空寫法的挑戰,但可以試著去習慣這個簡單優雅的小工具;
歡迎關注我的公眾號
相關推薦
java.util.Optional學習筆記
###三種Optional構造方法### 第一種. Optional.of(Object object):入參object不能為空,否則會丟擲空指標異常,檢視Optional原始碼發現會呼叫Objects.requireNonNull方法,裡面有判空: public static <T> T r
java.util.ListIterator學習筆記
概述 繼承結構 java.util.Iterator<E> << java.util.ListIterator 基本特性 列表迭代器並不持有當前元素的引用,其持有的遊標是位於列表連個元素之間。可以通過呼叫nex
java.util.Set學習筆記
概述 Set的概念與其在數學上的意義相同,是一種不允許存在重複元素的特殊集合,即:在一個Set中不包含滿足條件e1.equals(e2)的元素對e1和e2。Set介面在從Collection中繼承的介面的基礎上,增加了額外的限制條件,主要包括的方法為:構造
java.util.LinkedList學習筆記
概述 繼承結構 類描述 如繼承結構所示,LinkedList是兩個介面(List和Deque)的混合實現。其實現了List介面中所有的可選操作,並且LinkedList允許所有元素(包括null)的插入和訪問操作。LinkedLis
java.util.AbstractCollection學習筆記
前言 由今天開始,正式開始學習java.util包中的collection介面,及其相關類,並在該部落格賬號中進行更新,儘量每天一更,如果在部落格中存在錯誤,歡迎各位在留言區進行指證,相互交流,共同進步。 今天將從基本的AbstractCollection類
深入理解Java虛擬機- 學習筆記 - 虛擬機類加載機制
支持 pub eth 獲取 事件 必須 string 沒有 字節碼 虛擬機把描述類的數據從Class文件加載道內存,並對數據進行校驗,轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。在Java裏,類型的加載、連接和初始化過程都是在程序
Java核心技術學習筆記-繼承
java 繼承按照我們中文通俗的理解是不需要付出努力,就獲得別人的能力或資產,比如繼承父輩的家產,繼承父輩的表達能力,繼承父輩的外貌等等。在類裏面的繼承,可以理解不需要重新開發代碼,就能復用父類的方法和域。 在繼承關系裏面,可以分為父類和子類,子類繼承父類,那子類就有了跟父類一樣對外的方法
java System類學習筆記
lis per += start spa getprop ext static puts java 中 System 類 最常見到 System.out.println(); System類 定義為 public final class System extends Obj
學在前面——《瘋狂JAVA講義》學習筆記
要求 能夠 java對象 數據 頁面 hiberna spring 桌面 消失 一直放棄JAVA,覺得身為前端掌握html、css、js就可以勝任工作了,但是最近組裏後臺太忙了,有時候感覺只要在後臺改一點東西就能滿足前臺所需要的數據了,但是自己卻不會改,後臺還木有空,於
Java 設計模式學習筆記1——策略模式(Duck例子)
利用 實例化 top 而是 實現 學習筆記 left ng- 多個 0、假設現有工程(Duck)中遇到為類添加功能的問題,如何設計類添加新的功能? 1、利用繼承提供的Duck(鴨子)的行為會導致哪些缺點? (1)代碼在多個子類中重復 (2)很多男知道所有鴨子的全部行為
java 新特性學習筆記
sets arp string get pen option ring true read java 1.7 Files.write(path,list,StandardCharsets.UTF_8,StandardOpenOption.APPEND); St
Java集合框架學習筆記
引用 dex set集合 第一次 5.4 sof oid code over 本文為學習筆記,學習課程為慕課網Java入門第三季中的集合框架部分,若需要研究文中的代碼,可前往下載。http://www.imooc.com/learn/110 1. List(Collec
Java設計模式學習筆記,三:建造者模式
() stat sys pri builder 統一 return tengine str 建造者模式:實現了構建和裝配的解耦,即對象的各個子組件單獨構建,再進行裝配,從而建造完整對象。 該模式適用於構建較為復雜的對象(多個子組件)。 不同的構建者,使用相同的裝配者,可以建
Java語言基礎學習筆記(七)
day tez lec mdk abd err .com mar mdm 烈7A茨諳9m繁5暗MChttp://www.zcool.com.cn/collection/ZMTg3NzE1Njg=.html 3馗iC蓖17握WM啦http://www.zcool.com.cn
Java註冊登陸學習筆記
java註冊登陸學習筆記import java.util.Scanner;//用戶類class Users{String username;String password;public Users(String username,String password) {this.username = userna
java集合類學習筆記之LinkList
prev strong 內部數據 ins 屬性 aced 裏的 row return 1、簡述 LinkList的底層其實就是一個雙向鏈表,所謂的鏈表就是一個LinkList內部靜態靜態類(Node),對LinkList的所有操作本質上就是通過對LinkList中新
java集合類學習筆記之LinkedHashMap
super 增長 remove sta extend red for normal 順序 1、簡述 LinkedHashMap是HashMap的子類,他們最大的不同是,HashMap內部維護的是一個單向的鏈表數組,而LinkedHashMap內部維護的是一個雙向的鏈
Java使用Redis學習筆記
users 添加 進行 ember ali redis服務器 [] 排序 ktr 如果我們使用Java操作Redis, 需要確保已經安裝了 redis 服務及 Java redis 驅動。 Maven項目可以直接在pom.xml中加入jedis包驅動: &
java集合的學習筆記
搜狗 tac 查詢 功能 ash 應該 情況下 內容 方式 不知不覺也到了java集合這一章的學習,這因該是挺重要的一個章節,因為所有的程序都離不開數據,而一個良好的數據結構和算法應該是程序的靈魂吧。 今天對自己所初步了解的做一個總結: 數據結構是計算機存儲、組織數據的方式
Thinking in Java 第二章學習筆記
包含 的確 隨著 c++ 一個 變化 new 寄存器 我們 Java雖基於C++,但相比之下,Java是一種更加純粹的面向對象程序設計語言。 在Java的世界裏,幾乎一切都是對象,而Java中的全部工作則是定義類,產生那些類的對象,以及發送消息給這些對象。 盡管