溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

怎么在Java中利用Streams對(duì)異常進(jìn)行處理

發(fā)布時(shí)間:2021-01-18 16:08:57 來(lái)源:億速云 閱讀:243 作者:Leah 欄目:編程語(yǔ)言

本篇文章為大家展示了怎么在Java中利用Streams對(duì)異常進(jìn)行處理,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

前言:

Stream API 和 Lambda 是Java8的重要特性讓我們可以使用更具功能性的語(yǔ)法風(fēng)格。但是在編寫(xiě)的代碼時(shí)候一個(gè)更大的問(wèn)題是如何處理lambda中的已檢查異常。

但是不能直接調(diào)用從Lambda拋出異常!但是可以在Lambda中做一個(gè)簡(jiǎn)單的try-catch并將異常包裝成一個(gè)RuntimeException。

/**###很顯然這不是一種好的表現(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);
  }

換一種可讀性比較好的方式呢?

/**將函數(shù)體提取到一個(gè)單獨(dú)的方法中,并調(diào)用新方法做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

在許多情況下對(duì)于一些運(yùn)行時(shí)異常的捕捉都使用 RuntimeException 也可以在lambda內(nèi)部調(diào)用。如果每個(gè)調(diào)用都進(jìn)行運(yùn)行時(shí)異常的捕獲,重復(fù)代碼就出現(xiàn)了。所以:將它抽象為實(shí)用函數(shù),每次需要的時(shí)候調(diào)用它!

//定義一個(gè)檢查接口
@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);
  }
 };
}
/**調(diào)用公共wrap 進(jìn)行異常處理*/
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

使用流時(shí)如果發(fā)生異常不希望停止處理流,Either類(lèi)型是函數(shù)式語(yǔ)言中的常見(jiàn)類(lèi)型而不是Java的一部分。與Java中的Optional類(lèi)型類(lèi)似,Either是具有兩種可能性的通用包裝器。例如,如果我們有一個(gè)Either值,那么這個(gè)值可以包含String類(lèi)型或Integer類(lèi)型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 +")";
  }
}

讓函數(shù)返回Either 而不是拋出一個(gè)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));
  }
 };
}
/**調(diào)用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);
}

上述內(nèi)容就是怎么在Java中利用Streams對(duì)異常進(jìn)行處理,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI