Java 创建仅用于流中的新变量

Java 创建仅用于流中的新变量,java,java-8,java-stream,Java,Java 8,Java Stream,假设我们有以下一段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

假设我们有以下一段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变量只被分配一次,那么它就可以工作,但要完成这一任务,必须将整个代码包在一个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方法引发异常,请考虑将原始异常包装到您自己的异常中。当然,这取决于方法在应用程序逻辑中的位置。如果你认为它是一种低级的方法,IOExt就非常适合这个目的。如果您认为它更高级,您应该创建自己的异常,反映该方法的业务逻辑。
在这两种情况下,不要忘记在readFromFile方法中正确处理输入文件的关闭,尤其是在异常情况下。您可以使用Java 7功能。

问题出在您未显示的代码中—您的注释行:

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方法引发异常,请考虑将原始异常包装到您自己的异常中。当然,这取决于方法在应用程序逻辑中的位置。如果你认为它是一种低级的方法,IOExt就非常适合这个目的。如果您认为它更高级,您应该创建自己的异常,反映该方法的业务逻辑。
在这两种情况下,不要忘记在readFromFile方法中正确处理输入文件的关闭,尤其是在异常情况下。您可以使用Java 7功能。

有什么问题吗?这是一种观察。编辑:对不起,我现在看到了。问题在最后一段:有没有其他更好的方法来处理这个问题?编辑:没问题。您看到的问题是,指针所在的映射字段位于堆栈上,即方法堆栈框架中。当您在这里使用lambda表达式时,有可能会获取该值并将其存储在某个地方。如果您这样做了,然后您的方法结束了,那么指针将指向无效的位置,堆栈帧将消失。当您将引用设为最终引用时,或者在本例中,实际上是最终引用时,您允许编译器将引用复制到堆中的位置,而不是堆栈帧中指向字段的指针。@LouisWasserman如果我将所有内容移到try块中,它就会起作用,但是我特别想知道如何处理这种情况,即声明在try-block外部,赋值在try-block内部。我将其内容分为两个方法,类似于:initMap和processMap。第一个读取文件,处理异常并返回最终映射,第二个使用它。问题是什么?这是一种观察。编辑:对不起,我现在看到了。问题在最后一段:有没有其他更好的方法来处理这个问题?编辑:没问题。您看到的问题是,指针所在的映射字段位于堆栈上,即方法堆栈框架中。当您在这里使用lambda表达式时,有可能会获取该值并将其存储在某个地方。如果您这样做了,然后您的方法结束了,那么指针将指向无效的位置,堆栈帧将消失。当您将引用设为最终引用时,或者在本例中,实际上是最终引用时,您允许编译器将引用复制到堆中的位置,而不是堆栈帧中指向字段的指针。@LouisWasserman如果我将所有内容移到try块中,它就会起作用,但我特别想知道如何处理这个案件
在我看来,这里的根本问题是主方法做两件不同的事情。我将其内容分为两个方法,类似于:initMap和processMap。第一个读取文件,处理异常并返回最终映射,第二个使用它。+1您为我省去了编写类似内容的麻烦。:-与1相关的另一点是readFromFile必须捕获IOException,因为它打开并读取文件,并且必须可靠地关闭它。如果它得到异常,它已经检测到这种情况,因此能够向调用方返回一些合理的信息,例如空映射。@StuartMarks:我也知道readFromFile一定已经捕获了IOException,但我认为它会重新抛出它,甚至只是向上传递。你提醒正确的结束是对的。我将相应地编辑我的回复。谢谢你帮我省去了写类似东西的麻烦与1相关的另一点是readFromFile必须捕获IOException,因为它打开并读取文件,并且必须可靠地关闭它。如果它得到异常,它已经检测到这种情况,因此能够向调用方返回一些合理的信息,例如空映射。@StuartMarks:我也知道readFromFile一定已经捕获了IOException,但我认为它会重新抛出它,甚至只是向上传递。你提醒正确的结束是对的。我将相应地编辑我的回复。谢谢