Optional的使用

一、空指針問題與Optional的引入      
需求:根據人獲取他買的車保險名字。

Person:

1 package com.cy.java8;
2 
3 import lombok.Data;
4 
5 @Data
6 public class Person {
7 
8     private Car car;
9 }
View Code

Car:

1 package com.cy.java8;
2 
3 import lombok.Data;
4 
5 @Data
6 public class Car {
7 
8     private Insurance insurance;
9 }
View Code

Insurance:

1 package com.cy.java8;
2 
3 import lombok.Data;
4 
5 @Data
6 public class Insurance {
7 
8     private String name;
9 }
View Code
 1 package com.cy.java8;
 2 
 3 public class NullPointerException {
 4 
 5     public static void main(String[] args) {
 6         String insuracneName = getInsuranceName(new Person());
 7         
 8     }
 9 
10     /**
11      *  根據Person獲取保險的名字,直接這麼寫肯定拋空指針異常
12      */
13     private static String getInsuranceName(Person person){
14         return person.getCar().getInsurance().getName();
15     }
16 
17     /**
18      * 於是加上非空判斷
19      * 如果嵌套比較深,這種判斷比較麻煩,代碼可讀性很差
20      */
21     private static String getInsuranceName2(Person person){
22         if(null != person){
23             Car car = person.getCar();
24             if(null != car){
25                 Insurance insurance = car.getInsurance();
26                 if(null != insurance){
27                     return insurance.getName();
28                 }
29             }
30         }
31         return "UNKNOWN";
32     }
33 
34     /**
35      * 使用多個return語句來避免上面的這種嵌套
36      * 看起來是清晰了一些,但是還是很囉嗦
37      */
38     private static String getInsuranceName3(Person person){
39         final String defaultValue = "UNKNOWN";
40         if(null == person){
41             return  defaultValue;
42         }
43 
44         Car car = person.getCar();
45         if(null == car){
46             return defaultValue;
47         }
48 
49         Insurance insurance = car.getInsurance();
50         if(null == insurance){
51             return defaultValue;
52         }
53 
54         return insurance.getName();
55     }
56 
57     /**
58      * 使用Optional解決上面的問題
59      */
60 
61 }

二、Optional的api介紹        
解決上面的問題之前,先介紹下Optional的API
of
empty
ofNullable

get
orElse
orElseGet
orElseThrow

isPresent ifPresent

代碼舉例:

 1 package com.cy.java8;
 2 
 3 import java.util.Optional;
 4 
 5 public class OptionalUsage {
 6 
 7     public static void main(String[] args) {
 8         //創建一個空的Optional
 9         Optional<Insurance> optional = Optional.empty();
10 
11         //根據insurance作爲value創建optional,如果insurance爲null,報空指針
12         Insurance insurance = new Insurance();
13         Optional<Insurance> optional1 = Optional.of(insurance);
14 
15         //對前面兩個的綜合,如果insurance爲null,返回empty
16         Optional<Insurance> optional2 = Optional.ofNullable(null);
17 
18         //orElseGet:如果有值則返回,沒有值則返回elseGet括號裏的,括號裏是Suppiler
19         optional2.orElseGet(Insurance::new);
20 
21         optional2.orElse(new Insurance());
22 
23         //optional2.orElseThrow(() -> new RuntimeException("Not have a value"));
24 
25         /**
26          * filter
27          */
28         Insurance insurance1 = optional1.filter(i -> i.getName() == null).get();
29         System.out.println(insurance1);
30 
31         /**
32          * map
33          */
34         Optional<String> nameOptional = optional1.map(i -> i.getName());
35         String s = nameOptional.orElse("empty value");
36         System.out.println(s);
37 
38         /**
39          * isPresent ifPresent
40          */
41         Insurance insurance3 = new Insurance();
42         insurance3.setName("xiao wang");
43         Optional<Insurance> optional3 = Optional.of(insurance3);
44         Optional<String> nameOptional3 = optional3.filter(i -> i.getName().equals("xiao wang")).map(i -> i.getName());
45         System.out.println(nameOptional3.isPresent());
46         nameOptional3.ifPresent(i -> System.out.println("insurance name is :" + i));
47 
48         /**
49          * optional判斷空寫法
50          */
51         System.out.println(getInsuranceName(null));
52         System.out.println(getInsuranceNameByOptional(null));
53     }
54 
55     private static String getInsuranceName(Insurance insurance){
56         if(null == insurance){
57             return "unknown";
58         }
59         return insurance.getName();
60     }
61 
62     private static String getInsuranceNameByOptional(Insurance insurance){
63         return Optional.ofNullable(insurance).map(Insurance::getName).orElse("unknown");
64     }
65 }

打印結果:

Insurance(name=null)
empty value
true
insurance name is :xiao wang
unknown
unknown  

 

三、使用Optional解決上面的判空問題

需要改寫Person、Car

Person:

 1 package com.cy.java8;
 2 
 3 import lombok.Data;
 4 
 5 import java.util.Optional;
 6 
 7 @Data
 8 public class Person {
 9     private Optional<Car> car = Optional.empty();
10 }
View Code

Car:

 1 package com.cy.java8;
 2 
 3 import lombok.Data;
 4 
 5 import java.util.Optional;
 6 
 7 @Data
 8 public class Car {
 9 
10     private Optional<Insurance> insurance = Optional.empty();
11 }
View Code

Insurance:

1 package com.cy.java8;
2 
3 import lombok.Data;
4 
5 @Data
6 public class Insurance {
7 
8     private String name;
9 }
View Code
 1 package com.cy.java8;
 2 
 3 import java.util.Optional;
 4 
 5 public class OptionalInAction {
 6 
 7     public static void main(String[] args) {
 8         System.out.println(getInsuranceNameByOptional(null));
 9         System.out.println(getInsuranceNameByOptional(new Person()));
10     }
11 
12     private static String getInsuranceNameByOptional(Person person) {
13         String insuranceName = Optional.ofNullable(person)
14                                         .flatMap((p) -> p.getCar())
15                                         .flatMap(c -> c.getInsurance())
16                                         .map(i -> i.getName()).orElse("unknown");
17         return insuranceName;
18     }
19 
20 }

打印如下:

unknown
unknown

 

----

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章