1. 程式人生 > >java.util.Optional學習筆記

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的使用是在習慣上對之前判空寫法的挑戰,但可以試著去習慣這個簡單優雅的小工具;

歡迎關注我的公眾號

在這裡   
 
 </div> 
 <div class=

相關推薦

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中的全部工作則是定義類,產生那些類的對象,以及發送消息給這些對象。   盡管