详解Java Streams 中的异常处理

2025-05-29 0 78

前言:

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
/**###很显然这不是一种好的表现方式##**/

/**

* 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
/**将函数体提取到一个单独的方法中,并调用新方法做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内部调用。如果每个调用都进行运行时异常的捕获,重复代码就出现了。所以:将它抽象为实用函数,每次需要的时候调用它!

?

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

使用流时如果发生异常不希望停止处理流,either类型是函数式语言中的常见类型而不是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 +")";

}

}

让函数返回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 捕获异常继续执行*/

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 。建议您创建一个抽象进行调用,这样您就不会每次try/catch。也可以使用 either 或其他类型来包装函数的结果,使流不会终止。

以上所述是小编给大家介绍的java streams 中的异常处理详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对快网idc网站的支持!

原文链接:https://blog.csdn.net/u011663149/article/details/88661591

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 详解Java Streams 中的异常处理 https://www.kuaiidc.com/109296.html

相关文章

发表评论
暂无评论