1. 程式人生 > >Java9系列第7篇:Java.util.Optional優化與增強

Java9系列第7篇:Java.util.Optional優化與增強

![](https://img2020.cnblogs.com/other/1815316/202010/1815316-20201020065916157-395982535.png) 我計劃在後續的一段時間內,寫一系列關於java 9的文章,雖然java 9 不像Java 8或者Java 11那樣的核心java版本,但是還是有很多的特性值得關注。期待您能關注我,我將把java 9 寫成一系列的文章,大概十篇左右,本文是第7篇。 * [java9系列文章訪問地址](http://www.zimug.com/tag/java9) `java.util.Optional`是在Java 8版本中新增的類,一定程度上可以改善程式設計過程中的NullPointException的問題。在Java 9中對這個類新增了一些方法進行增強,下面我們一起來看一下,順便也回顧一下在Java 8中它的用法。 ## 一、Java9的ifPresentOrElse(Consumer,Runnable) ### 1.1.Java 9 中的增強 如果存在值,則此新方法將執行給定的Consumer操作,否則執行給定的Runnable操作。下面的程式碼先使用Java 8的的Stream流過濾3的倍數,然後通過findFirst找到第一個3的倍數。如果找到一個這樣的值,就print控制檯打印出來;如果沒找到一個這樣的值,就輸出"沒有找到3的倍數" > ifPresentOrElse(Consumer,Runnable)的語義可以解釋為:ifPresent就Consumer,OrElse就Runnable。這是Java 9 才有的增強方法。 ~~~ IntStream.of(1, 2, 4) .filter(i -> i % 3 == 0) .findFirst() .ifPresentOrElse(System.out::println, () -> { System.out.println("沒有找到3的倍數"); }); ~~~ 在1、2、4中沒有3的倍數,所以輸出結果如下 ~~~ 沒有找到3的倍數 ~~~ 如果是下面的2、6、8陣列被過濾,最終控制檯輸出結果為:6 ~~~ IntStream.of(2, 6, 8) .filter(i -> i % 3 == 0) .findFirst() .ifPresentOrElse(System.out::println, () -> { System.out.println("沒有找到3的倍數"); }); // 6 ~~~ ### 1.2.回顧一下Java 8中的寫法 #### Java 8 Optional.isPresent(): 如果使用Java 8 ,沒有`ifPresentOrElse(Consumer,Runnable)`方法,上文中同樣的程式碼你應該是這樣寫的:自己去寫if和else進行判斷。同樣輸出:沒有找到3的倍數 ~~~ OptionalInt opt = IntStream.of(1, 2, 4) .filter(i -> i % 3 == 0) .findFirst(); if (opt.isPresent()) { System.out.println(opt.getAsInt()); } else { System.out.println("沒有找到3的倍數"); } ~~~ #### Java 8 Optional.ifPresent(): `ifPresent()`方法在值不存在的時候,沒有提供一個可選的操作。所以下面的程式碼在執行之後,沒有orElse動作,沒有任何輸出,這樣不是很友好。 ~~~ IntStream.of(1, 2, 4) .filter(i -> i % 3 == 0) .findFirst() .ifPresent(System.out::println); ~~~ #### Java 8 Optional.orElse(): `orElse()`方法在value返回值為空的之後,給出一個預設值。下文程式碼中給出一個預設值-1。 ~~~ int result = IntStream.of(1, 2, 4) .filter(i -> i % 3 == 0) .findFirst() .orElse(-1); System.out.println(result); //-1 ~~~ ## 二、Java9的Optional.or(Supplier) 該方法在找不到值的時候,生成一個新的Optional出來。下文程式碼過濾陣列['a', 'b', 'c'],isDigit判斷陣列中是否有數字字元,明顯沒有,所以findFirst找不到一個這樣的值。所以生成一個預設值: `Optional.of('0')` ~~~ char digit = Stream.of('a', 'b', 'c') .filter(e -> Character.isDigit(e)) .findFirst() .or(() -> Optional.of('0')).get(); System.out.println(digit); //0 ~~~ #### Java8 中的 orElseGet() Java 8中的`Optional.orElseGet()`方法也具備同樣的功能。下文程式碼過濾陣列['a', 'b', 'c'],isDigit判斷陣列中是否有數字字元,明顯沒有,所以findFirst找不到一個這樣的值。所以通過orElseGet獲取一個預設值: `'0'` ~~~ char result = Stream.of('a', 'b', 'c') .filter(c -> Character.isDigit(c)) .findFirst() .orElseGet(()->'0'); System.out.println(result); //0 ~~~ ## 三、Java9的Optional.stream() 在本例中`Optional.stream()`方法返回僅包含一個最大值元素的Stream流。如果該值不存在,則返回空Stream: ~~~ OptionalInt opt1 = IntStream.of(2, 5, 6).max(); //求最大值 OptionalInt opt2 = IntStream.of(1, 3, 7).max(); //求最大值 IntStream.concat(opt1.stream(), opt2.stream()) //將2個流合併 .forEach(System.out::println); //將合併後的流資料列印 ~~~ 控制檯輸出的結果如下: ~~~ 6 7 ~~~ ## 歡迎關注我的部落格,裡面有很多精品合集 * 本文轉載註明出處(必須帶連線,不能只轉文字):[字母哥部落格](http://www.zimug.com)。 **覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力!** 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。 * [《手摸手教你學Spring Boot2.0》]( https://www.kancloud.cn/hanxt/springboot2/content ) * [《Spring Security-JWT-OAuth2一本通》](https://www.kancloud.cn/hanxt/springsecurity/content) * [《實戰前後端分離RBAC許可權管理系統》](https://www.kancloud.cn/hanxt/vue-spring/content) * [《實戰SpringCloud微服務從青銅到王者》](https://www.kancloud.cn/hanxt/springcloud/content) * [《VUE深入淺出系列》](https://www.kancloud.cn/hanxt/vuejs2/