Optional in Java with Examples - Java 147

Optional in Java with Examples – Java 147

Optional 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 常見範例。

發佈留言