Table of Contents
ToggleOptional in Java with Examples
是一個容器物件,它可能包含也可能不包含非空值,提供了依賴於所含值是否存在的方法, 如: orElse 如果值不存在則傳回預設值,簡化 NullPointerException 的顯式檢查,提高了程式碼的可讀性, Optional in Java 介紹常見的 orElse 、 orElseGet 、 orElseThrow 等方法,本篇增加了範例,並透過單元測試來驗證產出結果。
檔案目錄
./
+- src
+- test
| +- org
| +- ruoxue
| +- java_147
| +- optional
| +- OptionalWithExamplesTest.java
單元測試
Optional Java 提供取得、傳回預設值、拋出例外等操作 Optional 。
orElse
建立 Optional 容器,取得容器內的值,若值為 null 則傳回預設值。
public static String getDefaultValue() {
System.out.println("Call getDefaultValue()");
return "DEFAULT_VALUE";
}
@Test
public void orElse() {
Optional<String> opt = Optional.ofNullable("Beef");
String result = opt.orElse("DEFAULT_VALUE");
System.out.println(result);
assertEquals("Beef", result);
opt = Optional.ofNullable(null);
result = opt.orElse("DEFAULT_VALUE");
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
Optional<Integer> intOpt = Optional.ofNullable(147);
int intResult = intOpt.orElse(0);
System.out.println(intResult);
assertEquals(147, intResult);
intOpt = Optional.ofNullable(null);
intResult = intOpt.orElse(0);
System.out.println(intResult);
assertEquals(0, intResult);
Optional<List<String>> listOpt = Optional.ofNullable(new ArrayList<>(Arrays.asList("Beef", "Chicken", "Duck")));
List<String> listResult = listOpt.orElse(new ArrayList<>());
System.out.println(listResult);
assertEquals(3, listResult.size());
listOpt = Optional.ofNullable(null);
listResult = listOpt.orElse(new ArrayList<>());
System.out.println(listResult);
assertEquals(0, listResult.size());
}
Beef
DEFAULT_VALUE
147
0
[Beef, Chicken, Duck]
[]
orElseGet
Optional Java 建立 Optional 容器,取得容器內的值,若值為 null 則傳回預設值。
@Test
public void orElseGet() {
Optional<String> opt = Optional.ofNullable("Beef");
String result = opt.orElseGet(() -> "DEFAULT_VALUE");
System.out.println(result);
assertEquals("Beef", result);
opt = Optional.ofNullable(null);
result = opt.orElseGet(() -> "DEFAULT_VALUE");
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
opt = Optional.ofNullable(null);
result = opt.orElseGet(OptionalWithExamplesTest::getDefaultValue);
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
Optional<Integer> intOpt = Optional.ofNullable(147);
int intResult = intOpt.orElseGet(() -> 0);
System.out.println(intResult);
assertEquals(147, intResult);
intOpt = Optional.ofNullable(null);
intResult = intOpt.orElseGet(() -> 0);
System.out.println(intResult);
assertEquals(0, intResult);
Optional<List<String>> listOpt = Optional.ofNullable(new ArrayList<>(Arrays.asList("Beef", "Chicken", "Duck")));
List<String> listResult = listOpt.orElseGet(() -> new ArrayList<>());
System.out.println(listResult);
assertEquals(3, listResult.size());
listOpt = Optional.ofNullable(null);
listResult = listOpt.orElseGet(ArrayList::new);
System.out.println(listResult);
assertEquals(0, listResult.size());
}
Beef
DEFAULT_VALUE
Call getDefaultValue()
DEFAULT_VALUE
147
0
[Beef, Chicken, Duck]
[]
orElse_vs_orElseGet
Optional Java 建立 Optional 容器,取得容器內的值,若值為 null 則傳回預設值,兩者的區別在於,當值存在時, orElse 也會執行取得預設值的方法,比 orElseGet 多執行一次方法,比較沒有效率,而 orElseGet 當值存在時,並不會執行取得預設值的方法。
@Test
public void orElse_vs_orElseGet() {
Optional<String> opt = Optional.ofNullable("Beef");
String result = opt.orElse(getDefaultValue());
System.out.println(result);
assertEquals("Beef", result);
opt = Optional.ofNullable("Chicken");
result = opt.orElseGet(() -> getDefaultValue());
System.out.println(result);
assertEquals("Chicken", result);
opt = Optional.ofNullable(null);
result = opt.orElse(getDefaultValue());
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
opt = Optional.ofNullable(null);
result = opt.orElseGet(OptionalWithExamplesTest::getDefaultValue);
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
}
Call getDefaultValue()
Beef
Chicken
Call getDefaultValue()
DEFAULT_VALUE
Call getDefaultValue()
DEFAULT_VALUE
orElseThrow
Optional Java 建立 Optional 容器,取得容器內的值,若值為 null 則拋出例外。
@Test(expected = IllegalArgumentException.class)
public void orElseThrow() {
Optional<String> opt = Optional.ofNullable(null);
String result = opt.orElseThrow(IllegalArgumentException::new);
System.out.println(result);
assertFalse(opt.isPresent());
}
java.lang.IllegalArgumentException
at java.util.Optional.orElseThrow(Optional.java:290)
at org.ruoxue.java_147.optional.OptionalWithExamplesTest.orElseThrow(OptionalWithExamplesTest.java:116)
OptionalWithExamplesTest.java
Java Optional 新增單元測試,驗證是否符合預期。
package org.ruoxue.java_147.optional;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.junit.Test;
public class OptionalWithExamplesTest {
public static String getDefaultValue() {
System.out.println("Call getDefaultValue()");
return "DEFAULT_VALUE";
}
@Test
public void orElse() {
Optional<String> opt = Optional.ofNullable("Beef");
String result = opt.orElse("DEFAULT_VALUE");
System.out.println(result);
assertEquals("Beef", result);
opt = Optional.ofNullable(null);
result = opt.orElse("DEFAULT_VALUE");
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
Optional<Integer> intOpt = Optional.ofNullable(147);
int intResult = intOpt.orElse(0);
System.out.println(intResult);
assertEquals(147, intResult);
intOpt = Optional.ofNullable(null);
intResult = intOpt.orElse(0);
System.out.println(intResult);
assertEquals(0, intResult);
Optional<List<String>> listOpt = Optional.ofNullable(new ArrayList<>(Arrays.asList("Beef", "Chicken", "Duck")));
List<String> listResult = listOpt.orElse(new ArrayList<>());
System.out.println(listResult);
assertEquals(3, listResult.size());
listOpt = Optional.ofNullable(null);
listResult = listOpt.orElse(new ArrayList<>());
System.out.println(listResult);
assertEquals(0, listResult.size());
}
@Test
public void orElseGet() {
Optional<String> opt = Optional.ofNullable("Beef");
String result = opt.orElseGet(() -> "DEFAULT_VALUE");
System.out.println(result);
assertEquals("Beef", result);
opt = Optional.ofNullable(null);
result = opt.orElseGet(() -> "DEFAULT_VALUE");
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
opt = Optional.ofNullable(null);
result = opt.orElseGet(OptionalWithExamplesTest::getDefaultValue);
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
Optional<Integer> intOpt = Optional.ofNullable(147);
int intResult = intOpt.orElseGet(() -> 0);
System.out.println(intResult);
assertEquals(147, intResult);
intOpt = Optional.ofNullable(null);
intResult = intOpt.orElseGet(() -> 0);
System.out.println(intResult);
assertEquals(0, intResult);
Optional<List<String>> listOpt = Optional.ofNullable(new ArrayList<>(Arrays.asList("Beef", "Chicken", "Duck")));
List<String> listResult = listOpt.orElseGet(() -> new ArrayList<>());
System.out.println(listResult);
assertEquals(3, listResult.size());
listOpt = Optional.ofNullable(null);
listResult = listOpt.orElseGet(ArrayList::new);
System.out.println(listResult);
assertEquals(0, listResult.size());
}
@Test
public void orElse_vs_orElseGet() {
Optional<String> opt = Optional.ofNullable("Beef");
String result = opt.orElse(getDefaultValue());
System.out.println(result);
assertEquals("Beef", result);
opt = Optional.ofNullable("Chicken");
result = opt.orElseGet(() -> getDefaultValue());
System.out.println(result);
assertEquals("Chicken", result);
opt = Optional.ofNullable(null);
result = opt.orElse(getDefaultValue());
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
opt = Optional.ofNullable(null);
result = opt.orElseGet(OptionalWithExamplesTest::getDefaultValue);
System.out.println(result);
assertEquals("DEFAULT_VALUE", result);
}
@Test(expected = IllegalArgumentException.class)
public void orElseThrow() {
Optional<String> opt = Optional.ofNullable(null);
String result = opt.orElseThrow(IllegalArgumentException::new);
System.out.println(result);
assertFalse(opt.isPresent());
}
}
心得分享
Java Optional Example 提供取得或不存在時傳回預設值或是拋出例外,可以不再使用 if 判斷式檢查物件是否為 null 值,尤其是物件內又包含其他物件,巢狀的 if 判斷式,讓程式碼相當難於閱讀與除錯, Java Optional 在應用上相當廣泛,熟悉這些方法的操作,像是: orElse 、 orElseGet 、 orElseThrow 等,能夠提高開發效率,提供了幾種 Optional 常見範例。