假设我们有以下一段Java代码。

public static void main(String[] args) {
    Map<Integer, Integer> map = null;

    try {
        map = readFromFile(); //Method that reads from file, throws IOException
    }
    catch (IOException e) {
        //do something
    }

    List<Integer> list = new ArrayList<Integer>();
    list.stream().map(x -> map.get(x)).collect(Collectors.toList());
}


上面的代码无法编译,因为map不是最终的或实际上不是最终的。但是,当我们用其他变量替换map时,代码会编译。替换后的最后两行代码如下所示。

Map<Integer,Integer> mapReplacement = map;
list.stream().map(x -> mapReplacement.get(x)).collect(Collectors.toList());


我觉得奇怪的是,必须将同一映射分配给另一个变量,以便能够在流中使用它。还有其他(也许更好)的方式来处理此问题吗?如果将map变量仅分配给一次,那将是可行的,但是要实现这一点,必须将整个代码片段包装在try块中,这似乎不是我的方法。

最佳答案

问题出乎意料的是您尚未显示的代码-注释行:)

catch (IOException e) {
    //do something
}


如果您的readFromFile()方法确实引发异常,您将怎么办?

1.继续处理

您将继续处理空白地图吗?因此,您的readFromFile()然后应返回一个空映射,并且不会引发异常。 (或者您可以将方法包装到另一个方法中。)

public static void test1(String[] args) {
    final Map<Integer, Integer> map = readFromFile();
    final List<Integer> list = new ArrayList<>();
    list.stream().map(x -> map.get(x)).collect(Collectors.toList());
}


2.停止处理

您会停止进一步处理吗?然后只需从方法返回即可。 (当然,您不仅应该吞下该异常,还应让客户端方法以某种方式知道。)

public static void test1(String[] args) {
    final Map<Integer, Integer> map;

    try {
        map = readFromFile();
    }
    catch (IOException e) {
        // handle the exceptional situation
        return; // or throw another exception, but leave the method
    }

    final List<Integer> list = new ArrayList<>();
    list.stream().map(x -> map.get(x)).collect(Collectors.toList());
}


添加:

如果希望您的readFromFile()方法引发异常,请考虑将原始异常包装到您自己的异常中。当然,这取决于该方法在应用程序逻辑中的位置。如果您将其视为低级方法,则IOException非常适合此目的。如果您认为它更高级,则应创建自己的异常,以反映该方法的业务逻辑。

在这两种情况下,请不要忘记在readFromFile()方法中正确处理输入文件的CLOSING,尤其是在发生异常的情况下。您可以使用Java 7 try-with-resources功能。

08-05 01:24