软件编程
位置:首页>> 软件编程>> java编程>> 详解Java Streams 中的异常处理

详解Java Streams 中的异常处理

作者:Go Big Or Go Home  发布时间:2021-09-03 11:26:11 

标签: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<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);
 }

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


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


//定义一个检查接口
@FunctionalInterface
public interface CheckedFunction<T,R> {
 R apply(T t) throws Exception;
}

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


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


/**调用公共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>。


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.


//只记录异常
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));
 }
};
}


/**调用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 中的异常处理详解整合网站的支持!

来源:https://blog.csdn.net/u011663149/article/details/88661591

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com