Java8新特性 Optional 類的使用
阿新 • • 發佈:2021-12-24
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()方法
- 與orElse類似,區別在於值為空時,就執行傳入的 Lambda 表示式,並返回其執行結果。
User result = Optional.ofNullable(user2).orElseGet( () -> user1);
- 如果值不為空,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());
}