首页  >  文章  >  Java  >  过滤流时如何处理 Java 8 Lambda 表达式中的异常?

过滤流时如何处理 Java 8 Lambda 表达式中的异常?

Patricia Arquette
Patricia Arquette原创
2024-10-26 04:54:03820浏览

How to Handle Exceptions in Java 8 Lambda Expressions When Filtering Streams?

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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn