optional介紹
optional是jdk1.8提供的一個新類,希望可以通過該類的引入解決令人煩躁的null判斷問題,非常好用。個人理解:這個類是一個包裝類,將要操作的java bean封裝到該類的對象里面,同時將一些常用的判斷邏輯封裝為成員方法,結合lambda語法,實現比較優雅的鏈式調用。現在對optional的api使用做一個簡單的說明。
api介紹
optional的所有的方法如下圖所示,這些api大致可以分為以下幾類:
1、構建api:構建一個optional對象;方法有:empty( )、of( )、ofnullable( );
2、獲取api:獲取optional對象里包裝的值;方法有:get( )、orelse( )、orelseget( )、orelsethrow( );
3、轉換api:將optional對象里包裝的值轉換成一個新的值;方法有:map( )、flatmap( );
4、判斷api:對optional對象里包裝的值做一些邏輯判斷;方法有:filter( )、ispresent( )、ifpresent( );
api使用方法
首先準備一個pojo類
1
2
3
4
5
6
7
8
9
10
11
|
@data @noargsconstructor @allargsconstructor @equalsandhashcode @tostring public class userinfo { private string username; private string password; private integer age; private string gender; } |
構建類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@test public void testbuildoptional() { // 構建一個value為null的optional對象; optional<userinfo> userinfoemptyopt = optional.empty(); // 構建一個value不可以為null的optional對象,如果of()的入參為null會報空指針異常; optional<userinfo> userinfoopt = optional.of( new userinfo( "阿飛" , "123456" , 15 , "man" )); // 構建一個value可以為null的optional對象; optional<userinfo> userinfonullopt = optional.ofnullable( null ); system.out.println(userinfoemptyopt); system.out.println(userinfoopt); system.out.println(userinfonullopt); // 輸出如下: // optional.empty // optional[userinfo(username=阿飛, password=123456, age=15, gender=man)] // optional.empty } |
獲取類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
@test public void testgetoptionalvalue() { optional<userinfo> userinfoemptyopt = optional.empty(); optional<userinfo> userinfoopt = optional.of( new userinfo( "阿飛" , "123456" , 15 , "man" )); // 直接獲取,注意如果value==null,會報nosuchelementexception異常 userinfo userinfo1 = userinfoopt.get(); // orelse可以傳入一個userinfo類型的對象作為默認值;當value!=null時,返回value值;當value==null時,返回默認值作為代替; userinfo userinfo2 = userinfoemptyopt.orelse( new userinfo( "阿飛1" , "123456" , 15 , "man" )); // orelseget和orelse不同的是orelseget可以傳入一段lambda表達式;當value!=null時,返回value值;當value==null時,使用該lambda返回的對象作為默認值; userinfo userinfo3 = userinfoemptyopt.orelseget(() -> new userinfo( "阿飛2" , "123456" , 15 , "man" )); // orelsethrow可以傳入一段lambda表達式,lambda返回一個exception;當value!=null時,返回value值;當value==null時,拋出該異常; userinfo userinfo4 = userinfoopt.orelsethrow(nullpointerexception:: new ); system.out.println(userinfo1); system.out.println(userinfo2); system.out.println(userinfo3); system.out.println(userinfo4); // 輸出如下: // userinfo(username=阿飛, password=123456, age=15, gender=man) // userinfo(username=阿飛1, password=123456, age=15, gender=man) // userinfo(username=阿飛2, password=123456, age=15, gender=man) // userinfo(username=阿飛, password=123456, age=15, gender=man) } |
轉換類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@test public void testmapoptionalvalue() { optional<userinfo> userinfoopt = optional.of( new userinfo( "阿飛" , "123456" , 15 , "man" )); // 原來value的類型是userinfo,經過map轉換為optional<string> optional<string> username = userinfoopt.map(userinfo::getusername); // 當map的入參也是一個optional時,經過map轉化后會形成optional<optional<string>>這種嵌套結構;但flatmap可以把這種嵌套結構打平; optional<optional<string>> unflatmap = userinfoopt.map(user -> optional.of(user.getusername())); optional<string> flatmap = userinfoopt.flatmap(user -> optional.of(user.getusername())); system.out.println(username); system.out.println(unflatmap); system.out.println(flatmap); // 輸出如下: // optional[阿飛] // optional[optional[阿飛]] // optional[阿飛] } |
判斷類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
@test public void testjudgeoptionalvalue() { optional<userinfo> userinfoemptyopt = optional.empty(); optional<userinfo> userinfoopt = optional.of( new userinfo( "阿飛" , "123456" , 15 , "man" )); // filter傳入一個lambda,lambda返回值為boolean;true:不做任何改變,false:返回一個空的optional; optional<userinfo> userinfo = userinfoopt.filter(user -> "錯誤的密碼" .equals(user.getpassword())); system.out.println(userinfo); // ispresent就是判斷value是不是null;我們在調用get之前,一定要先調用ispresent,因為直接如果value是null,直接調用get會報異常; if (userinfoemptyopt.ispresent()) { userinfo value = userinfoemptyopt.get(); system.out.println( "optional value:" + value); } else { system.out.println( "optional value==null" ); } // ifpresent傳入一段lambda,當value!=null時,執行里面的邏輯;當當value==null時,啥都不干; userinfoopt.ifpresent(value -> system.out.println( "optional value:" + value)); // 輸入如下: // optional.empty // optional value==null // optional value:userinfo(username=阿飛, password=123456, age=15, gender=man) } |
試一下這些api吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
package com.fly.optional; import lombok.allargsconstructor; import lombok.data; import lombok.noargsconstructor; import lombok.tostring; import org.junit.test; import org.omg.cosnaming.namingcontextpackage.notfound; import java.math.bigdecimal; import java.util.optional; public class optiondemo { @data @noargsconstructor @allargsconstructor @tostring static class employee { private long id; private string name; private boolean leader; } @data @noargsconstructor @allargsconstructor @tostring static class leader { private long employeeid; private bigdecimal bonus; } /** * 找到id為1的員工,如果有獎金就打印出來,沒有就打印沒有獎金; * @throws notfound */ @test public void tst() throws notfound { optional<leader> leader = optional.ofnullable(getemployeebyid(1l).filter(employee::getleader).map(employee::getid).flatmap( this ::getleaderbyemployeeid).orelse( null )); if (leader.ispresent()) { optional.of(leader.map(leader::getbonus).map(bonus -> string.format( "員工id為1的leader獎金為:%s" , bonus)).orelse( "員工id為1的leader也沒有獎金" )).ifpresent(system.out::println); } else { system.out.println( "員工id為1的leader未找到,他可能只是一個基層員工,不配擁有獎金" ); } } private optional<employee> getemployeebyid( long id) { //return optional.of(new employee(1l, "大老板", boolean.true)); return optional.of( new employee(1l, "大老板" , boolean . false )); } private optional<leader> getleaderbyemployeeid( long employeeid) { //return employeeid == 1l ? optional.of(new leader(1l, bigdecimal.valueof(1000000000))) : optional.empty(); return employeeid == 1l ? optional.of( new leader(1l, null )) : optional.empty(); } } |
總結
到此這篇關于java8 optional的詳細使用的文章就介紹到這了,更多相關java8 optional使用內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_39087135/article/details/113866147