Reading a text file using the stream - Variable to lambda expression

advertisements

I am currently learning Java and reached a point where I am major confused with a (imo) minor problem.

I would like to read a text file, work with the string I have from each line, add a variable and continue. For example: I have a text file with three lines and I'd like to add a variable to the end of each line which gets upped by one for each line.

To break everything down I made an example program but I still do not get fully behind it.

My text file "test.txt" has three lines of text "Line1", "Line2" and "Line3" and I have an Integer named testNum with a value of 500 which I would like to up after each line.

My code is the following:

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++;
});

Now I understand that the issue lies in the lambda expression. Can someone explain to me why I need local variables for the lambda expression and am unable to access variables declared outside from it?

Moreover, I tried to change my code to use a for each instead but for each seems not applicable for "Stream", e.g.:

for(String line : readFileStream){
}

Thanks a lot in advance.


Generally, the time and place of creation of a lambda expression differs from the time and place of execution. Sometimes, a lambda expression is created in method A and executed in method B half minutes or hours later. And it might be executed on a different thread. So it would not be sensible to write to variables with method scope (i.e. stack variables that only exist while the method is executed). Read access to those variable is allowed as their value is 'copied' into the lambda expression at creation time.

In your case, it might be easier to give up streams and use the List version of Files.lines(...), so you can iterate via for-loop:

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