java - 如何以简洁的方式收集抛出异常的 Java 流操作的结果?

标签 java java-stream checked-exceptions

看看下面的代码片段,它试图将字符串列表转换为类对象列表:

public static List<Class<?>> f1(String... strings) {
    return
        Stream.of(strings)
        .map(s -> {
            try {
                return Class.forName(s);
            }
            catch (ClassNotFoundException e) {
                System.out.println(e.getMessage());
            }
            return null;
        })
        .collect(Collectors.toList());
}

由于 Java 处理流中已检查异常的方式(已详细讨论 here - 我也公然从中窃取了我的示例片段),您必须在 try-catch block 之后有额外的 return 语句。这将导致将不需要的空引用添加到 List 类型的结果中。

为了避免这种额外的空引用,我提出了以下函数,使用普通的旧过程循环获得了更好的结果:

public static List<Class<?>> f2(String... strings) {
    List<Class<?>> classes = new ArrayList<>();
    for (String s : strings) {
        try {
            classes.add(Class.forName(s));
        }
        catch (ClassNotFoundException e) {
            // Handle exception here
        }
    }
    return classes;
}

这个观察是否允许我以最佳实践建议的形式得出结论,可以像下面这样表达?

如果您需要调用一个在流中抛出异常的函数并且您不能使用 stream.parallel(),最好使用循环,因为:

  1. 无论如何,您都需要 try-catch block (尽管涉及在上述讨论中提供的抛出函数周围的某种包装器的棘手解决方案)

  2. 你的代码不会不够简洁(主要是因为1.)

  3. 如果出现异常,您的循环不会中断

你怎么看?

最佳答案

您可以在不引入必须在后续步骤中过滤的元素的情况下执行此操作:

public static List<Class<?>> f1(String... strings) {
    return Arrays.stream(strings)
        .flatMap(s -> {
            try { return Stream.of(Class.forName(s)); }
            catch(ClassNotFoundException e) { return null; }
        })
        .collect(Collectors.toList());
}

不过,这并不比循环解决方案更简洁。

但需要注意的是,这与checked exceptions无关。您希望在异常(exception)情况下继续,忽略失败的元素。 始终 要求您捕获 异常以实现此替代行为(默认情况下是将异常传播给调用者),无论异常是已检查还是未检查。已勾选的案例具有提醒您必须执行此操作的优点。

换句话说,Stream API 不允许您以简单的方式实现将检查异常传播给调用者的行为,但这无论如何不是您想要的。如果 Class.forName(String) 被设计为仅抛出未经检查的异常,则在 map 中省略 try … catch block 将导致整个操作在异常情况下通过将异常转发给调用者来中止。但是,如前所述,这不是您想要的。

关于java - 如何以简洁的方式收集抛出异常的 Java 流操作的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49537265/

相关文章:

.net - 列出方法可能抛出的所有异常

java - “找不到符号”或“无法解析符号”错误是什么意思?

java - 从 Stream 调用的 close() 方法如何指向 AbstractPipeline 抽象类中 close() 方法的实现?

java - 如何使用流相互检查两个数组

java - 是否可以在 Java 中禁用检查异常?

java - 为什么在这种情况下允许抛出已检查的异常类型?

java - @Immutable with @Entity and insertable=false and updateable=false on @Column

java - 有没有办法从现有代码库生成 checkstyle 的 supressions.xml 文件?

java - 如何将类传递给方法并调用该类的静态方法

java - 使用 Java 8 搜索字谜