1. 程式人生 > 其它 >Java8新特性 Optional 類的使用

Java8新特性 Optional 類的使用

Optional 類

定義與宣告

定義

  • Optional 類是一個可以為null的容器物件。它可以儲存型別T的值,或者僅僅儲存null。
  • Optional 類的引入可以不用顯式進行空值檢測。

類宣告

點選檢視程式碼

public final class Optional<T>
extends Object

使用

建立 Optional類物件

  • 包裝物件值為空。 Optional test1 = Optional.empty();
  • 包裝物件值非空。 Optional test2 = Optional.of("optional");
  • 包裝物件值允許為空。 Optional test3 = Optional.ofNullable(null);

常用方法

ifPresent()方法

  • 除了檢查是否有值,還接受一個consumer引數,如果物件不是空的,就執行傳入的 Lambda 表示式。
點選檢視程式碼
User user = User.builder().name(name).build();
Optional<User> opt = Optional.ofNullable(user);
opt.ifPresent( u -> assertEquals(user.getName(), u.getName()));//只有name不為null時執行斷言

orElse()方法

  • 如果包裝物件值非空,返回包裝物件值,否則返回入參的值
點選檢視程式碼
User user1 = User.builder().name(name).build();
User user2 = null;
User result1 = Optional.ofNullable(user1).orElse(user2);//因為user1非空,直接返回user1
User result1 = Optional.ofNullable(user2).orElse(user1);//因為user2為空,返回user1

orElseGet()方法

  1. 與orElse類似,區別在於值為空時,就執行傳入的 Lambda 表示式,並返回其執行結果。
    User result = Optional.ofNullable(user2).orElseGet( () -> user1);
  2. 如果值不為空,orElse()會執行後面的語句,而orElseGet()不會,效能上 orElseGet()更好。
點選檢視程式碼
@Test
public void givenPresentValue_whenCompare_thenOk() {
    User user = new User("[email protected]", "1234");
    logger.info("Using orElse");
    User result = Optional.ofNullable(user).orElse(createNewUser());
    logger.info("Using orElseGet");
    User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
}
private User createNewUser() {
    logger.debug("Creating New User");
    return new User("[email protected]", "1234");
}
輸出為:
Using orElse
Creating New User
Using orElseGet

orElseThrow()方法

  • 為空時返回異常
    User result = Optional.ofNullable(user).orElseThrow( () -> new IllegalArgumentException());

map()方法

  • map()方法將Optional中的包裝物件用傳入的Function函式進行運算,幷包裝成新的Optional物件(包裝物件的型別可能改變)
    String email = Optional.ofNullable(user).map(u -> u.getEmail()).orElse("[email protected]");//取出user中email作為新的optional物件值

flatMap()方法

  • 與 map 的區別在於 map會包裝一層Optional,而flatMap直接返回結果,將二維的Optional物件對映為一維的物件。
  • map和flatMap的原始碼如下
點選檢視程式碼
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Optional.ofNullable(mapper.apply(value));
        }
    }
 public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
        Objects.requireNonNull(mapper);
        if (!isPresent())
            return empty();
        else {
            return Objects.requireNonNull(mapper.apply(value));
        }
    }

filter()方法

  • 接受一個 Predicate 引數,返回測試結果為 true 的值。如果測試結果為 false,會返回一個空的 Optional。
點選檢視程式碼
@Test
public void whenFilter_thenOk() {
    User user = new User("[email protected]", "1234");
    Optional<User> result = Optional.ofNullable(user)
      .filter(u -> u.getEmail() != null && u.getEmail().contains("@"));

    assertTrue(result.isPresent());
}

參考:

  1. https://www.jianshu.com/p/d81a5f7c9c4e
  2. https://www.cnblogs.com/zhangboyu/p/7580262.html