前言:
stream api 和 lambda 是java8的重要特性讓我們可以使用更具功能性的語法風格。但是在編寫的代碼時候一個更大的問題是如何處理lambda中的已檢查異常。
但是不能直接調用從lambda拋出異常!但是可以在lambda中做一個簡單的try-catch并將異常包裝成一個runtimeexception。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/**###很顯然這不是一種好的表現(xiàn)方式##**/ /** * dosomething * @param item * @return */ private static object dosomething(string item) { system.out.println( "dosomething:\t" + item); return item; } public static void main(string[] args) { list<string> mylist = arrays.aslist( "1" , "2" , "3" , "4" , "5" , "6" ); mylist.stream().map(item -> { try { return dosomething(item); } catch (exception e) { throw new runtimeexception(e); } }).foreach(system.out::println); } |
換一種可讀性比較好的方式呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/**將函數(shù)體提取到一個單獨的方法中,并調用新方法做try-catch處理**/ private object dosomething(string item) { system.out.println( "dosomething:\t" + item); return item; } private object trysomething(string item) { try { return dosomething(item); } catch (exception e) { throw new runtimeexception(e); } } public void map() { list<string> mylist = arrays.aslist( "1" , "2" , "3" , "4" , "5" , "6" ); mylist.stream().map( this ::dosomething).foreach(system.out::println); } |
runtimeexception
在許多情況下對于一些運行時異常的捕捉都使用 runtimeexception 也可以在lambda內部調用。如果每個調用都進行運行時異常的捕獲,重復代碼就出現(xiàn)了。所以:將它抽象為實用函數(shù),每次需要的時候調用它!
1
2
3
4
5
|
//定義一個檢查接口 @functionalinterface public interface checkedfunction<t,r> { r apply(t t) throws exception; } |
您可以在此抽象接口中處理try-catch并將原始異常包裝到 runtimeexception 中。
1
2
3
4
5
6
7
8
9
|
public static <t,r> function<t,r> wrap(checkedfunction<t,r> checkedfunction) { return t -> { try { return checkedfunction.apply(t); } catch (exception e) { throw new runtimeexception(e); } }; } |
1
2
3
4
5
6
7
|
/**調用公共wrap 進行異常處理*/ public void map(){ list<string> mylist = arrays.aslist( "1" , "2" , "3" , "4" , "5" , "6" ); mylist.stream() .map(wrap(item -> dosomething(item))) .foreach(system.out::println); } |
either
使用流時如果發(fā)生異常不希望停止處理流,either類型是函數(shù)式語言中的常見類型而不是java的一部分。與java中的optional類型類似,either是具有兩種可能性的通用包裝器。例如,如果我們有一個either值,那么這個值可以包含string類型或integer類型either<string,integer>。
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
|
public class either<l, r> { private final l left; private final r right; private either(l left, r right) { this .left = left; this .right = right; } public static <l,r> either<l,r> left( l value) { return new either(value, null ); } public static <l,r> either<l,r> right( r value) { return new either( null , value); } public optional<l> getleft() { return optional.ofnullable(left); } public optional<r> getright() { return optional.ofnullable(right); } public boolean isleft() { return left != null ; } public boolean isright() { return right != null ; } public <t> optional<t> mapleft(function<? super l, t> mapper) { if (isleft()) { return optional.of(mapper.apply(left)); } return optional.empty(); } public <t> optional<t> mapright(function<? super r, t> mapper) { if (isright()) { return optional.of(mapper.apply(right)); } return optional.empty(); } public string tostring() { if (isleft()) { return "left(" + left + ")" ; } return "right(" + right + ")" ; } } |
讓函數(shù)返回either 而不是拋出一個exception.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
//只記錄異常 public static <t,r> function<t, either> lift(checkedfunction<t,r> function) { return t -> { try { return either.right(function.apply(t)); } catch (exception ex) { return either.left(ex); } }; } //記錄異常和值 public static <t,r> function<t, either> liftwithvalue(checkedfunction<t,r> function) { return t -> { try { return either.right(function.apply(t)); } catch (exception ex) { return either.left(pair.of(ex,t)); } }; } |
1
2
3
4
5
6
7
|
/**調用either.lift 捕獲異常繼續(xù)執(zhí)行*/ public void map(){ list<string> mylist = arrays.aslist( "1" , "2" , "3" , "4" , "5" , "6" ); mylist.stream() .map(either.lift(item -> dosomething(item))) .foreach(system.out::println); } |
總結:
如果你想在lambda中調用它checkedexception,你可以將其包裝成一個runtimeexception 。建議您創(chuàng)建一個抽象進行調用,這樣您就不會每次try/catch。也可以使用 either 或其他類型來包裝函數(shù)的結果,使流不會終止。
以上所述是小編給大家介紹的java streams 中的異常處理詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網(wǎng)站的支持!
原文鏈接:https://blog.csdn.net/u011663149/article/details/88661591