Search code examples
javaforeachjava-streamline-numbers

How to insert a counter into a Stream<String> .forEach()?


FileWriter writer = new FileWriter(output_file);
    int i = 0;

    try (Stream<String> lines = Files.lines(Paths.get(input_file))) {
        lines.forEach(line -> {
            try {
                writer.write(i + " # " + line + System.lineSeparator());
            } catch (Exception e) {
                e.printStackTrace();
            }   
        }
                    );
        writer.close();
    }

I need to write the line with the line number, so I tried to add a counter into the .forEach(), but I can't get it to work. I just don't know where to put the i++; into the code, randomly screwing around didn't help so far.


Solution

  • This is a good example of where you should rather use a good old fashioned for loop. While Files.lines() specifically gives a sequential stream, streams can be produced and processed out of order, so inserting counters and relying on their order is a rather bad habit to get into. If you still really want to do it, remember that anywhere you can use a lambda you can still use a full anonymous class. Anonymous classes are normal classes, and can as such have state.

    So in your example you could do like this:

    FileWriter writer = new FileWriter(output_file);
    
    try (Stream<String> lines = Files.lines(Paths.get(input_file))) {
        lines.forEach(new Consumer<String>() {
            int i = 0;
            void accept(String line) {
                try {
                    writer.write((i++) + " # " + line + System.lineSeparator());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        writer.close();
    }