使用stream读取文本文件 - lamba表达式中的变量

时间:2016-10-28 08:15:46

标签: java lambda java-8 java-stream

我目前正在学习Java,并且遇到了一个主要与(imo)小问题相混淆的问题。

我想阅读一个文本文件,使用每行的字符串,添加变量并继续。 例如:我有一个包含三行的文本文件,我想在每行的末尾添加一个变量,每行增加一个变量。

为了打破一切,我做了一个示例程序,但我仍然没有完全支持它。

我的文本文件“test.txt”有三行文本“Line1”,“Line2”和“Line3”,我有一个名为testNum的整数,其值为500,我想在每一行之后添加。< / p>

我的代码如下:

String fileName = "test.txt";
int testNum = 1024;

Stream<String> readFileStream = null;
try {
    readFileStream = Files.lines(Paths.get(fileName));

} catch (IOException e) {
    e.printStackTrace();
}
readFileStream.forEach( line -> {            
    System.out.println(line+testNum);
    testNum++;
});

现在我明白问题在于lambda表达式。有人可以向我解释为什么我需要lambda表达式的局部变量,并且无法访问从它外部声明的变量吗?

此外,我尝试将我的代码更改为使用for代替,但是每个代码似乎都不适用于“Stream”,例如:

for(String line : readFileStream){
}

提前多多感谢。

2 个答案:

答案 0 :(得分:1)

通常,创建lambda表达式的时间和地点与执行的时间和地点不同。有时,在方法A中创建lambda表达式,并在方法B中半分钟或几小时后执行。它可能在不同的线程上执行。因此,使用方法范围(即在执行方法时仅存在的堆栈变量)写入变量是不明智的。允许对这些变量进行读取访问,因为它们的值已被复制&#39;在创建时进入lambda表达式。

在您的情况下,放弃流并使用ListFiles.lines(...)可能更容易,因此您可以通过for循环进行迭代:

List<String> lines = Files.readAllLines(Paths.get(filename));
int testNum = 500;
for(String line : lines) {
    System.out.println(line + testNum);
    testNum++;
}

答案 1 :(得分:0)

如果要为此任务使用流,可以创建特定的字符串使用者https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html

String fileName = "test.txt";

Stream<String> readFileStream = null;
try {
    readFileStream = Files.lines(Paths.get(fileName));

} catch (IOException e) {
    e.printStackTrace();
}

readFileStream.forEach(
    new Consumer<String>() {
        int testNum = 1024;
        public void accept(String line) {
            try {
                System.out.println(line + testNum++);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
});