參考資料:
Java8 Optional用法和最佳實踐 - 掘金
一、背景
根據Oracle文檔,Optional是一個容器對象,可以包含也可以不包含非null值。Optional在Java 8中引入,目的是解決??NullPointerExceptions的問題。本質上,Optional是一個包裝器類,其中包含對其他對象的引用。在這種情況下,對象只是指向內存位置的指針,并且也可以指向任何內容。從其它角度看,Optional提供一種類型級解決方案來表示可選值而不是空引用。
在Optional之前
在Java 8之前,程序員將返回null而不是Optional。這種方法有一些缺點。一種是沒有明確的方法來表示null可能是一個特殊值。相比之下,在API中返回Optional是明確的聲明,其中可能沒有值。如果我們要確保不會出現空指針異常,則需要對每個引用進行顯式的空檢查,如下所示,我們都同意這是很多樣板。
// Life before Optionalprivate void getIsoCode( User user){if (user != null) {Address address = user.getAddress();if (address != null) {Country country = address.getCountry();if (country != null) {String isocode = country.getIsocode();if (isocode != null) {isocode = isocode.toUpperCase();}}}}}
為了避免上述繁雜 的? !=null? ,我們可以引入Optional
二、Optional類的對象創建
均為靜態方法創建
1. Optional.empty()
//第一種創建方式Optional<String> optional=Optional.empty();//判斷是否為空. 此時為 空null,System.out.println(optional.isEmpty());//判斷是否存在。此時不存在,返回falseSystem.out.println(optional.isPresent());//如果optional為null,則會出現異常. System.out.println(optional.get());
2.Optional.of()
//第二種創建方式//Optional<String> optional=Optional.of(null); //value 不能為null,不然會報錯Optional<String> optional1=Optional.of("123");System.out.println(optional1.get());
3. Optional.ofNullable()
三、檢查Optional的value是否存在
下面代碼中包含了3種判斷方法
Optional<String> optional=Optional.ofNullable(null);//1.boolean empty = optional.isEmpty();//2.boolean present = optional.isPresent();//3.optional.ifPresent(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println("一旦存在,就調用我這個方法");}});
這個filter方法,有點意思,可以自己去判斷是否滿足一個條件,滿足則創建一個新的Optional對象并且value跟所要判斷的optional的value一致。否則返回一個Optional.empty()
四、獲取value的方法
讓gpt解釋一下? orElse() 與orElseGet()的區別
五、Optional的最佳實踐
當你在編寫項目時使用 Optional 類型時,以下是一些最佳實踐建議:
-
不要將 Optional 用于方法參數或字段類型
- Optional 類型主要用于表示可能存在空值的返回值類型。
- 如果將其用于方法參數或字段類型,則可能會使代碼變得復雜,甚至不必要。
-
盡量避免使用 Optional 的 get() 方法
- Optional 的 get() 方法可以用于獲取 Optional 對象中的值,但如果 Optional 對象為空,則會拋出 NoSuchElementException 異常。
- 因此,為了避免異常的發生,最好使用其他方法來處理 Optional 對象的值,比如 orElse() 或 orElseGet()。
-
使用 Optional 來處理返回值為空的情況
- 如果一個方法可能返回 null,應該考慮使用 Optional 類型來代替。
- 這樣可以更明確地表示空值的含義,并提供更加優雅的語法來處理空值的情況。
-
使用 Optional 與 Stream API 結合使用
- Optional 和 Stream API 是 Java 8 中引入的兩個重要特性。
- 它們結合使用可以提高代碼的可讀性和簡潔性。
- 可以使用 Optional 的 filter() 和 map() 方法來對 Stream 進行過濾和轉換操作,從而生成新的 Optional 對象。
// 示例 1:使用 Optional 來處理返回值為空的情況
public Optional<String> getOptionalValue(String key) {String value = getValueByKey(key);return Optional.ofNullable(value);
}// 示例 2:使用 Optional 和 Stream API 進行過濾操作
public Optional<User> findUserByName(String name) {List<User> userList = getUserList();return userList.stream().filter(user -> user.getName().equals(name)).findFirst();
}// 示例 3:使用 orElse() 方法提供默認值
Optional<String> optional = Optional.empty();
String result = optional.orElse("default value");// 示例 4:使用 orElseGet() 方法提供默認值
Optional<String> optional = Optional.empty();
String result = optional.orElseGet(() -> generateDefaultValue());// 示例 5:使用 map() 方法將 Optional 對象中的值轉換為其他類型
Optional<String> optional = Optional.of("hello");
Optional<Integer> lengthOptional = optional.map(String::length);// 示例 6:使用 flatMap() 方法展開 Optional 對象
Optional<Optional<String>> optional = Optional.of(Optional.of("hello"));
Optional<String> flattenedOptional = optional.flatMap(Function.identity());
關于示例6的一些解釋: