【Java8】Optional你真的會(huì)用嗎?用好Optional這些騷操作,讓你

【Java8】Optional 詳解
1、 Optional介紹
傳統(tǒng)的寫(xiě)代碼方式經(jīng)常會(huì)遇到NullPointerException,這就需要我們?cè)诖a中經(jīng)常判空。而判空的寫(xiě)法又會(huì)顯得很累贅,這里就可以用到Optional來(lái)簡(jiǎn)化代碼。
① Optional是在java.util包下的一個(gè)用于代替null的一個(gè)工具類(lèi);
② Optional 是個(gè)容器:它可以保存類(lèi)型T的值,或者僅僅保存null。Optional提供很多有用的方法,這樣我們就不用顯式進(jìn)行空值檢測(cè)。
③ Optional 類(lèi)是一個(gè)可以為null的容器對(duì)象。如果值存在則isPresent()方法會(huì)返回true,調(diào)用get()方法會(huì)返回該對(duì)象。Optional 類(lèi)的引入很好的解決空指針異常。
2、構(gòu)建Optional對(duì)象
① 創(chuàng)建一個(gè)空的 Optional 實(shí)例
?Optional<String> emptyOptional = Optional.empty();
② 創(chuàng)建一個(gè) Optional 實(shí)例,當(dāng) t為null時(shí),拋出NullPointerException異常
?Optional<String> notNullOptional = Optional.of("aaa");
③ 創(chuàng)建一個(gè) Optional 實(shí)例,但當(dāng) t為null時(shí)不會(huì)拋出異常,而是返回一個(gè)空的實(shí)例
?Optional<String> notNullOptional = Optional.ofNullable("aaa");
3、 獲取Optional中的值
獲取optional實(shí)例中的對(duì)象,當(dāng)optional 容器為空時(shí)報(bào)錯(cuò),拋出NoSuchElementException,獲取前可以使用ifPresent進(jìn)行判斷。
?Optional<String> optional = Optional.of("Hello optional"); ????System.out.println("optional get is :"+optional.get()); ????optional.ifPresent(System.out::println);
4、判斷方法
?Optional<String> optional = Optional.of("aaa");
① 判斷optional是否為空,如果空則返回false,否則返回true
?System.out.println(optional.isPresent());
② 如果optional不為空,則將optional中的對(duì)象傳給Comsumer函數(shù)
?optional.ifPresent(System.out::println);
③ 檢查Optional實(shí)例是否有值,如果實(shí)例非null,就返回實(shí)例值,否則返回指定的其它值
?String aa = optional.orElse("haha"); ?System.out.println(aa);
④ 如果optional不為空,則返回optional中的對(duì)象;如果為null,則使用Supplier函數(shù)生成默認(rèn)值other
?optional.orElseGet(() -> "Default Value")
orElseGet(Supplier supplier):功能與orElse一樣,只不過(guò)orElseGet參數(shù)是一個(gè)對(duì)象
⑤ 如果optional不為空,則返回optional中的對(duì)象;如果為null,則拋出Supplier函數(shù)生成的異常
?String bb = optional.orElseThrow(() -> new Exception("拋出異常"));
⑥ filter(Predicate p):如果有值并且滿足條件,就返回該Optional,否則返回空Optional
?Optional<User> result = Optional.ofNullable(user).filter(u -> u.getEmail() != null && u.getEmail().contains("@"));
⑦ 如果optional不為空,則將optional中的對(duì)象 t 映射成另外一個(gè)對(duì)象 u,并將 u 存放到一個(gè)新的optional容器中。
?Optional<Integer> notNullToInteger = notNullOptional.map((value) -> 1);
5、Optional 的不正確使用案例
- 不要直接拿來(lái)做if-else的判定條件,這肯定不合理的:
?Optional<User> user = ...... ?if (user.isPresent()) { ??return user.getOrders(); ?} else { ??return Collections.emptyList(); ?}
而且get()要配合isPresent()才安全。
- 其次,盡量不要用 Optional 拿來(lái)做成員變量,特別是 pojo 的成員變量,這很容易讓讀 pojo 的框架出問(wèn)題。
- 再次,不要拿來(lái)做方法參數(shù),因?yàn)楹芸赡軐?xiě)成 if (user.isPresent()) {}式的代碼。
- 最后,Optional 的關(guān)注點(diǎn)在它的 value 的后續(xù)處理身上,如果這個(gè) value 只是一個(gè) flag,建議直接使用if-else;如果這個(gè) value 被用在多路返回里,也不能使用 Optional。