Java 8:Lambda-Streams - 按引發異常的方法進行過濾
Java 8 的lambda 表達式提供了強大的方法來操作和處理數據。但是,在處理可能引發異常的方法時,了解 lambda 表達式的限制並探索有效的解決方案非常重要。
問題:
考慮以下程式碼片段:
<code class="java">class Bank { public Set<String> getActiveAccountNumbers() throws IOException { Stream<Account> s = accounts.values().stream(); s = s.filter(a -> a.isActive()); Stream<String> ss = s.map(a -> a.getNumber()); return ss.collect(Collectors.toSet()); } } interface Account { boolean isActive() throws IOException; String getNumber() throws IOException; }</code>
由於 isActive 和 getNumber 方法拋出檢查異常,此程式碼無法編譯。僅僅捕捉周圍的 try-catch 區塊中的異常是不夠的,因為 lambda 表達式中未正確處理異常。
解決方案:
克服這個問題,我們需要在異常轉義 lambda 表達式之前捕獲它們。一種方法是使用未經檢查的異常,如以下修改後的程式碼片段所示:
<code class="java">s = s.filter(a -> { try { return a.isActive(); } catch (IOException e) { throw new UncheckedIOException(e); } });</code>
這裡,我們在lambda 內捕獲IOException 並拋出未經檢查的異常,確保它在lambda 內部已正確處理
或者,我們可以使用一個包裝器方法,將已檢查的異常轉換為未檢查的異常:
<code class="java">return s.filter(a -> uncheckCall(a::isActive)) .map(Account::getNumber) .collect(toSet()); public static <T> T uncheckCall(Callable<T> callable) { try { return callable.call(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } }</code>
這允許我們將lambda 表達式包裝在對uncheckCall 的呼叫中,後者處理在內部檢查異常,使lambda 表達式不受檢查異常聲明的影響。
其他注意事項:
需要注意的是,某些異常仍然可以逃脫lambda 表達式,即使使用建議的解決方案。例如,在計算收集操作期間引發的異常仍會從 lambda 傳播出去。
以上是過濾流時如何處理 Java 8 Lambda 表達式中的異常?的詳細內容。更多資訊請關注PHP中文網其他相關文章!