Optional簡化空值判斷,減少程式碼中的if-else程式碼塊

pad長世界第一發表於2020-11-26

為了防止空指標異常的出現,Java8中引入了一個新類Optional,對於它之前我們已經進行了簡單的實現。其本質就是通過Optional類對值進行封裝, 當有值的時候,會把該值封裝到Optional類中。如果沒有值的話,則會在該類封裝一個Empty

建立Optional物件

//empty()會直接返回一個空的Optional例項,內部不會存在任何值。
Optional<Student> studentOptional = Optional.empty();

//of()會返回一個存在值的Optional物件,並且該值不允許null的存在。如果呼叫該方法時傳入引數是null,則立刻丟擲NullPointerException,而不是等到你用這個物件時才丟擲,相當於進行了立即檢查。
Optional<Student> studentOptional = Optional.of(student);

//ofNullable()同樣也會返回一個存在值的Optional物件,但是它和of()最大的不同在於,它會對傳入的值進行判斷,如果傳入的值為null,其會呼叫empty()返回一個不包含內容的Optional,如果不為null,則會呼叫of()返回一個包含內容的Optional
Optional<Student> studentOptional = Optional.ofNullable(student);

isPresent()與ifPresent()應用

public class PresentDemo {
    public static void getStudentName(Student student){
        Optional<Student> studentOptional = Optional.ofNullable(student);
		//isPresent()只會單純做判斷
        if (studentOptional.isPresent()){
//存在
            System.out.println("student存在");
        }else {
            System.out.println("student不存在");
        }
//該方法在執行時,接收一個consumer函式式介面,如果value不為null,則通過consumer中的accept方法獲取該值。
        studentOptional.ifPresent((x)-> System.out.println("存在"));

    }
    public static void main(String[] args) {
        Student student = new Student();
        getStudentName(student);
    }
}

get()與orElseThrow()應用

get()的使用非常簡單,但不安全,因為其在獲取值的時候,如果值存在,則直接返回封裝在Optional中的值,如果不存在,則丟擲NoSuchElementException。因此它的使用前提是已經確定Optional中有值,否則沒有使用意義。

orElseThrow()當Optional中沒有值時,get()會直接丟擲NoSuchElementException,這樣的話,就存在了一定的侷限性,因為有時可能需要丟擲自定義異常。此時就可以使用orElseThrow(),它在取值時,如果Optional中沒有值時,可以丟擲自定義異常。

public class MyException extends Throwable {
public MyException() {
super();
}
public MyException(String message) {
super(message);
}
@Override
public String getMessage() {
return "exception message";
}
}
public class OrElseThrowDemo {
public static void getStudentInfo(Student student) {
Optional<Student> studentOptional = Optional.ofNullable(student);
try {
Student student1 = studentOptional.orElseThrow(MyException::new);
} catch (MyException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Student student = null;
getStudentInfo(student);
}
}

map()與flatMap()應用

//map的作用就是直接取值
if (studentOptional.isPresent()){
Optional<String> nameOptional = studentOptional.map(Student::getName);
}

在學生類中加新的屬性

//Student類新增Job屬性
private Optional<Job> job;
//Job類新增Company屬性
private Optional<ComPany> comPany;

如果想拿到上述的值,通過連環的map是拿不到的,因為每一次在呼叫的時候,都會對Optional的泛型進行改變,最終產生多層Optional巢狀的結構,這時就需要用到flatMap()

Optional<String> nameOptional =
studentOptional.flatMap(Student::getJob).flatMap(Job::getCompany).map(Company::getName);

filter()應用

對應著以前使用的equals方法,就是匹配

//傳統寫法
Company company = optional().get();
if("test".equals(company.getName)){
sout(company);


Optional<Company> company = companyOptional.filter(c ‐> "test".equals(c.getName()));
}

orElse()與orElseGet()應用

在取值的時候,如果值不存在,有時我們會考慮返回一個預設值。該需求就可以通過orElse()實現。其內部會判斷值是否為null,如果不為null,則返回該值,如果為null,則返回傳入的預設值。
orElseGet()也是用於當Optional中沒有值時,返回預設值的方法。但是它與orElse()的區別在於,它是延遲載入的。只有當Optional中沒有值是才會被呼叫。

public class Demo1 {
public static void getCompanyName(Student student) {
Optional<Student> studentOptional = Optional.ofNullable(student);
if (studentOptional.isPresent()) {
String value1 =
studentOptional.flatMap(Student::getJob).flatMap(Job::getCompany).map(Company::getName).orElse(g
et("a"));
String value2 =
studentOptional.flatMap(Student::getJob).flatMap(Job::getCompany).map(Company::getName).orElseGe
t(()>get("b"));
System.out.println("a: "+value1);
System.out.println("b: "+value2);
}
}
public static String get(String name) {
System.out.println(name + "執行了方法");
return "exec";
}
public static void main(String[] args) {
Company company = new Company();
//company.setName("test");
Optional<Company> companyOptional = Optional.of(company);
Job job = new Job();
job.setName("pm");
job.setCompany(companyOptional);
Optional<Job> jobOptional = Optional.of(job);
Student s1 = new Student();
s1.setName("張三");
s1.setJob(jobOptional);
getCompanyName(s1);
}
}
a執行了方法
b執行了方法
a: exec
b: exec
public class Demo1 {
public static void getCompanyName(Student student) {
Optional<Student> studentOptional = Optional.ofNullable(student);
if (studentOptional.isPresent()) {
String value1 =
studentOptional.flatMap(Student::getJob).flatMap(Job::getCompany).map(Company::getName).orElse(g
et("a"));
String value2 =
studentOptional.flatMap(Student::getJob).flatMap(Job::getCompany).map(Company::getName).orElseGe
t(()>get("b"));
System.out.println("a: "+value1);
System.out.println("b: "+value2);
}
}
public static String get(String name) {
System.out.println(name + "執行了方法");
return "exec";
}
public static void main(String[] args) {
Company company = new Company();
company.setName("test");
Optional<Company> companyOptional = Optional.of(company);
Job job = new Job();
job.setName("pm");
job.setCompany(companyOptional);
Optional<Job> jobOptional = Optional.of(job);
Student s1 = new Student();
s1.setName("張三");
s1.setJob(jobOptional);
getCompanyName(s1);
}
}
a執行了方法
a: test
b: test

相關文章