參考資料:https://www.baeldung.com/java-optional
https://mp.weixin.qq.com/s/P2kb4fswb4MHfb0Vut_kZg
1. 描述
Optional是java.util包中的一部分,所以要有相關的引用:
import java.util.Optional;
2. 創建Optional方法
2.1 empty,創建一個空的Optional
@Test public void whenCreatesEmptyOptional_thenCorrect() { Optional<String> empty = Optional.empty(); assertFalse(empty.isPresent()); }
2.2 of,創建Optional,使用of方法時,傳入不能為null,否則會報NullPointerException異常:
@Test public void givenNonNull_whenCreatesNonNullable_thenCorrect() { String name = "baeldung"; Optional<String> opt = Optional.of(name); assertTrue(opt.isPresent()); }
2.3 ofNullable,創建Optional,ofNullable方法是允許值為null的
@Test public void givenNonNull_whenCreatesNullable_thenCorrect() { String name = "baeldung"; Optional<String> opt = Optional.ofNullable(name); assertTrue(optionalName.isPresent()); }
3. 判斷Optional的值
3.1 isPrensent,判斷Optional是否有值,返回boolean類型,上面幾個創建例子都用了isPresent,源碼:
public boolean isPresent() {
return value != null; }
3.2 ifPrensent,如果Optional有值,執行后面函數
@Test public void givenOptional_whenIfPresentWorks_thenCorrect() { Optional<String> opt = Optional.of("baeldung"); opt.ifPresent(name -> System.out.println(name.length())); }
如果在Optional為null的情況下,直接使用ifPresent有可能會報NullPointerException,所以就有了下面幾個函數。
3.3 orElse和orElseGet,返回Optional包裹的值,如果值為null,則返回函數內的默認值,這兩個方法的區別在於orElse后面跟默認值對象,orElseGet跟的是表達式函數。
@Test public void whenOrElseWorks_thenCorrect() { String nullName = null; String name = Optional.ofNullable(nullName).orElse("john"); assertEquals("john", name); } @Test public void whenOrElseGetWorks_thenCorrect() { String nullName = null; String name = Optional.ofNullable(nullName).orElseGet(() -> "john"); assertEquals("john", name); }
3.4 orElseThrow,返回Optional包裹的值,如果值為null,則拋出異常
@Test(expected = IllegalArgumentException.class) public void whenOrElseThrowWorks_thenCorrect() { String nullName = null; String name = Optional.ofNullable(nullName).orElseThrow(IllegalArgumentException::new); }
3.5 get,返回Optional包裹的值,如果值為null,會拋出NoSuchElementException異常
@Test(expected = NoSuchElementException.class) public void givenOptionalWithNull_whenGetThrowsException_thenCorrect() { Optional<String> opt = Optional.ofNullable(null); String name = opt.get(); }
4. Optional值的操作
4.1 map,將一個值轉換成另一個值,下面的例子是返回字符串的長度,沒有則返回默認值0
@Test public void givenOptional_whenMapWorks_thenCorrect2() { String name = "baeldung"; Optional<String> nameOptional = Optional.of(name); int len = nameOptional.map(String::length).orElse(0); assertEquals(8, len); }
4.2 filter,用於過濾。接收一個函數式接口,當符合接口時,則返回一個Optional對象,否則返回一個空的Optional對象
@Test public void whenOptionalFilterWorks_thenCorrect() { Integer year = 2016; Optional<Integer> yearOptional = Optional.of(year); boolean is2016 = yearOptional.filter(y -> y == 2016).isPresent(); assertTrue(is2016); boolean is2017 = yearOptional.filter(y -> y == 2017).isPresent(); assertFalse(is2017); }
5. 與Lambda表達式結合使用,優化代碼
5.1 條件為true就執行
優化前:
String person = "wo are you";
if(person != null){
System.out.println(person);
}
優化后:
Optional<String> optional = Optional.of("wo are you");
optional.ifPresent(System.out::println);
5.2 條件為true就返回,false返回默認值
優化前:
String person = "wo are you"; if(person != null){ System.out.println(person); } else { return DEFAULT_VALUE; }
優化后:
Optional<String> optional = Optional.of("wo are you"); return optional.orElse(DEFAULT_VALUE);
5.3 條件為true就返回,false調用函數生成
優化前:
String person = "wo are you"; if(person != null){ System.out.println(person); } else { return createPerson();
}
優化后:
Optional<String> optional = Optional.of("wo are you"); return optional.orElseGet(t -> createPerson());
5.4 連環null檢查
優化前:
Person person = new Person("Tom"); if(person != null){ String name = person.getLastName(); if(name != null){ return name.toLowerCase(); } else { return null; } } else { return null; }
優化后:
Optional<Person> optional = Optional.ofNullable(new Person("Tom")); return optional.map(p -> p.getLastName()).map(name -> name.toUpperCase()).orElse(null);