JDK8的Optional用法


參考資料: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);

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM