java stream异常,详解Java Streams 中的异常处理

前言:

Stream API 和 Lambda 是Java8的重要特性让我们可以使用更具功能性的语法风格。但是在编写的代码时候一个更大的问题是如何处理lambda中的已检查异常。

但是不能直接调用从Lambda抛出异常!但是可以在Lambda中做一个简单的try-catch并将异常包装成一个RuntimeException。

/**###很显然这不是一种好的表现方式##**/

/**

* 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 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);

}

换一种可读性比较好的方式呢?

/**将函数体提取到一个单独的方法中,并调用新方法做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 myList = Arrays.asList("1", "2", "3", "4", "5", "6");

myList.stream().map(this::doSomething).forEach(System.out::println);

}

RuntimeException

在许多情况下对于一些运行时异常的捕捉都使用 RuntimeException 也可以在lambda内部调用。如果每个调用都进行运行时异常的捕获,重复代码就出现了。所以:将它抽象为实用函数,每次需要的时候调用它!

//定义一个检查接口

@FunctionalInterface

public interface CheckedFunction {

R apply(T t) throws Exception;

}

您可以在此抽象接口中处理try-catch并将原始异常包装到 RuntimeException 中。

public static Function wrap(CheckedFunction checkedFunction) {

return t -> {

try {

return checkedFunction.apply(t);

} catch (Exception e) {

throw new RuntimeException(e);

}

};

}

/**调用公共wrap 进行异常处理*/

public void map(){

List 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。

public class Either {

private final L left;

private final R right;

private Either(L left, R right) {

this.left = left;

this.right = right;

}

public static Either Left( L value) {

return new Either(value, null);

}

public static Either Right( R value) {

return new Either(null, value);

}

public Optional getLeft() {

return Optional.ofNullable(left);

}

public Optional getRight() {

return Optional.ofNullable(right);

}

public boolean isLeft() {

return left != null;

}

public boolean isRight() {

return right != null;

}

public Optional mapLeft(Function super L, T> mapper) {

if (isLeft()) {

return Optional.of(mapper.apply(left));

}

return Optional.empty();

}

public Optional 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.

//只记录异常

public static Function lift(CheckedFunction function) {

return t -> {

try {

return Either.Right(function.apply(t));

} catch (Exception ex) {

return Either.Left(ex);

}

};

}

//记录异常和值

public static Function liftWithValue(CheckedFunction function) {

return t -> {

try {

return Either.Right(function.apply(t));

} catch (Exception ex) {

return Either.Left(Pair.of(ex,t));

}

};

}

/**调用Either.lift 捕获异常继续执行*/

public void map(){

List 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 中的异常处理详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值