什麼是Optional容器類
Optional 類(java.util.Optional) 是一個容器類,代表一個值存在或不存在,原來用 null 表示一個值不存在,現在 Optional 可以更好的表達這個概念。並且可以避免空指標異常。
Optional類常用方法:
Optional.of(T t) : 建立一個 Optional 例項。
Optional.empty() : 建立一個空的 Optional 例項。
Optional.ofNullable(T t):若 t 不為 null,建立 Optional 例項,否則建立空例項。
isPresent() : 判斷是否包含值。
orElse(T t) : 如果呼叫物件包含值,返回該值,否則返回t。
orElseGet(Supplier s) :如果呼叫物件包含值,返回該值,否則返回 s 獲取的值。
orElseThrow(Supplier es) : 當遇到一個不存在的值的時候,並不返回一個預設值,而是丟擲異常。
map(Function f): 如果有值對其處理,並返回處理後的Optional,否則返回 Optional.empty()。
flatMap(Function mapper):與 map 類似,要求返回值必須是Optional。
filter(Predicate p):接收一個函式式介面,當符合介面時,則返回一個Optional物件,否則返回一個空的Optional物件。
示例:
1 import org.junit.Test; 2 import java.util.Optional; 3 /* 4 * Optional 容器類:用於儘量避免空指標異常 5 * Optional.of(T t) : 建立一個 Optional 例項 6 * Optional.empty() : 建立一個空的 Optional 例項 7 * Optional.ofNullable(T t):若 t 不為 null,建立 Optional 例項,否則建立空例項 8 * isPresent() : 判斷是否包含值 9 * ifPresent(Consumer<? super T> consumer) 判斷是否包含值,再執行 consumer 10 * orElse(T t) : 如果呼叫物件包含值,返回該值,否則返回t 11 * orElseGet(Supplier s) :如果呼叫物件包含值,返回該值,否則返回 s 獲取的值 12 * orElseThrow(Supplier<? extends X> exceptionSupplier) : 當遇到一個不存在的值的時候,並不返回一個預設值,而是丟擲異常 13 * map(Function f): 如果有值對其處理,並返回處理後的Optional,否則返回 Optional.empty() 14 * flatMap(Function mapper):與 map 類似,要求返回值必須是Optional 15 * filter(Predicate<? super T> predicate):接收一個函式式介面,當符合介面時,則返回一個Optional物件,否則返回一個空的Optional物件 16 * 17 * map、flatMap 和 filter 的使用方法和 StreamAPI 中的一樣 18 */ 19 public class TestOptional { 20 21 22 /** 23 * 建立 Optional 例項 24 */ 25 @Test 26 public void test1(){ 27 28 // Optional.empty() : 建立一個空的 Optional 例項 29 Optional<String> empty = Optional.empty(); 30 System.out.println(empty);// 輸出結果:Optional.empty 31 //System.out.println(empty.get());// 報錯:java.util.NoSuchElementException: No value present 32 33 // Optional.of(T t) : 建立一個 Optional 例項 34 Optional<Employee> eop = Optional.of(new Employee()); 35 System.out.println(eop);// 輸出結果:Optional[Employee{name='null', age=null, gender=null, salary=null, status=null}] 36 System.out.println(eop.get());//輸出結果:Employee{name='null', age=null, gender=null, salary=null, status=null} 37 38 //注意:Optional.of(T t) 中,傳遞給of()的值不可以為空,否則會丟擲空指標異常 39 //Optional<Employee> eop1 = Optional.of(null);//這一行直接報錯:java.lang.NullPointerException 40 41 //Optional.ofNullable(T t):若 t 不為 null,建立 Optional 例項,否則建立空例項 42 //所以,在建立Optional物件時,如果傳入的引數不確定是否會為Null時,就可以使用 Optional.ofNullable(T t) 方式建立例項。 43 Optional<Object> op = Optional.ofNullable(null);//這樣的效果和 Optional.empty() 一樣 44 System.out.println(op);//Optional.empty 45 op = Optional.ofNullable(new Employee());// 46 System.out.println(op);//Optional[Employee{name='null', age=null, gender=null, salary=null, status=null}] 47 } 48 49 50 /** 51 * isPresent() : 判斷是否包含值 52 * ifPresent(Consumer<? super T> consumer) 判斷是否包含值,再執行 consumer 53 */ 54 @Test 55 public void test2(){ 56 Optional<Employee> opt = Optional.of(new Employee()); 57 System.out.println(opt.isPresent());//輸出結果:true 58 opt = Optional.ofNullable(null); 59 System.out.println(opt.isPresent());//輸出結果:false 60 opt.ifPresent(employee -> System.out.println(employee));// 如果 opt.isPresent() 為false ,這裡就不輸出,否則就輸出 employee 61 } 62 63 /** 64 * orElse(T t) : 如果呼叫物件包含值,返回該值,否則返回t 65 * orElseGet(Supplier s) :如果呼叫物件包含值,返回該值,否則返回 s 獲取的值 66 */ 67 @Test 68 public void test3(){ 69 //Optional<Employee> opt = Optional.of(new Employee()); 70 Optional<Employee> opt = Optional.ofNullable(null); 71 /*Employee emp = opt.orElse(new Employee("張三",20)); 72 System.out.println(emp);*/ 73 74 int condition = 2;//模擬條件 75 Employee emp = opt.orElseGet(()-> { 76 if (condition == 1){ 77 return new Employee("李四"); 78 }else if (condition == 2){ 79 return new Employee("王二麻子"); 80 }else { 81 return new Employee("趙六"); 82 } 83 }); 84 System.out.println(emp); 85 } 86 /** 87 * orElseThrow(Supplier<? extends X> exceptionSupplier) : 當遇到一個不存在的值的時候,並不返回一個預設值,而是丟擲異常 88 */ 89 @Test 90 public void test4(){ 91 Object obj = Optional.ofNullable(null).orElseThrow(IllegalArgumentException::new);//當引數為null,則丟擲一個不合法的引數異常 92 System.out.println(obj); 93 } 94 95 96 }
備註:map、flatMap 和 filter 的使用方法和 StreamAPI 中的一樣,如需瞭解詳細使用方法,請參考:Stream API 詳解