Java 8: Lambda-Streams, Filtration by Method with Exception Handling
In Java 8, lambda expressions in streams efficiently filter elements. However, when dealing with methods that throw checked exceptions like IOException, complications can arise.
The following code snippet demonstrates this issue:
<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>
This code fails to compile as it cannot handle the IOException thrown by the isActive and getNumber methods within the lambda expressions.
To resolve this, we need to catch the exception before it escapes the lambda:
<code class="java">s = s.filter(a -> { try { return a.isActive(); } catch (IOException e) { throw new UncheckedIOException(e); } });</code>
As the lambda is evaluated in a different context where the checked exception is not declared, we wrap the checked exception within an unchecked one.
Alternatively, you can use a method that defuses the compiler's exception checking:
<code class="java">return s.filter(a -> uncheckCall(a::isActive)) .map(Account::getNumber) .collect(toSet());</code>
Where uncheckCall is defined as:
<code class="java">public static <T> T uncheckCall(Callable<T> callable) { try { return callable.call(); } catch (Exception e) { sneakyThrow(e); return null; // Unreachable but needed to satisfy compiler } }</code>
This method effectively converts checked exceptions to unchecked ones. However, it should be used with caution, as it can lead to unexpected behavior if not handled correctly.
The above is the detailed content of How to Handle Checked Exceptions When Using Lambda Expressions with Streams in Java 8?. For more information, please follow other related articles on the PHP Chinese website!