您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么在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對異常進行處理,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。