温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

怎么在Java中利用Streams对异常进行处理

发布时间:2021-01-18 16:08:57 来源:亿速云 阅读:252 作者:Leah 栏目:编程语言

本篇文章为大家展示了怎么在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);
}

上述内容就是怎么在Java中利用Streams对异常进行处理,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI