Java Optional 的 orElse() 和 orElseGet() 的區別
1. 接收的參數不同
orElse()
方法以一個自定義類型的數據作為參數
public T orElse(T t)
orElseGet()
方法以一個Supplier
類型的數據作為參數
public T orElseGet(Supplier<? extends T> other)
2. 程序的執行過程不同
以下面一段代碼為例:
public static void main(String[] args) { String[] names = new String[]{"zhang", "wang", "li", "zhao", "wu"}; Optional.of("wang").orElse(getRandomName(names)); // 執行該句時會打印"Generating a name..." Optional.of("wang").orElseGet(() -> getRandomName(names)); } public static String getRandomName(String[] names) { System.out.println("Generating a name..."); Random random = new Random(); return names[random.nextInt(5)]; }
在上述代碼在運行Optional.of("wang").orElse(getRandomName(names))
時會打印"Generating a name...",而在運行Optional.of("wang").orElseGet(() -> getRandomName(names))
時沒有任何輸出,這說明了orElse()
中的函數getRandomName
被調用了,而orElseGet()
中的Lambda表達式沒有執行。
產生上述現象的原因是,無論Optional對象中的值是否為空,orElse()
函數都會執行;而由於orElseGet()
中的參數為一個Supplier
方法,該方法的特點是僅在必要的時候執行,因此只有在Optional對象中的值為空時,orElseGet()
中的Supplier
方法才會執行。
3. 性能差異
由於orElse()
和orElseGet()
執行過程的差異,orElseGet()
方法的執行效率相對而言也更快,這是因為他會跳過不必要的方法調用。
因此,只有當默認值已經事先定義的情況下,才使用orElse()
,否則使用orElseGet()
更好。
=================================================================================
使用map
函數返回對象,使用flatMap
返回Optional
。例如:
public static void main(String[] args) { Optional<String> s = Optional.of("input"); System.out.println(s.map(Test::getOutput)); System.out.println(s.flatMap(Test::getOutputOpt)); } static Optional<String> getOutputOpt(String input) { return input == null ? Optional.empty() : Optional.of("output for " + input); } static String getOutput(String input) { return input == null ? null : "output for " + input; }
這兩個語句輸出相同的東西。