recorrer lista index ejemplo java foreach java-stream line-numbers

java - lista - ¿Cómo insertar un contador en un Stream<String>.forEach()?



recorrer lista java 8 (3)

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

Necesito escribir la línea con el número de línea, así que intenté agregar un contador en el .forEach (), pero no puedo hacer que funcione. Simplemente no sé dónde poner el i ++; en el código, atornillar al azar no ayudó hasta ahora.


Como se indica en el documento de Java :

Cualquier variable local, parámetro formal o parámetro de excepción usado pero no declarado en una expresión lambda debe ser declarado final o ser efectivamente final (§4.12.4), o se produce un error de compilación cuando se intenta el uso.

Significa que tu variable tiene que ser final o efectivamente final. Desea agregar un contador en forEach y para eso puede usar un AtomicInteger como lo sugiere OldCurumudgeon, que es un enfoque preferido de IMO.

Creo que también puedes usar una matriz que tiene solo un valor 0 que puedes usar como contador. Comprueba y hazme saber si el siguiente ejemplo te funciona:

public void test() throws IOException { FileWriter writer = new FileWriter("OutFile.txt"); final int[] count = {0}; try (Stream<String> lines = Files.lines(Paths.get("InFile.txt"))) { lines.forEach(line -> { try { count[0]++; writer.write(count[0] + " # " + line + System.lineSeparator()); } catch (Exception e) { e.printStackTrace(); } } ); writer.close(); } }


Este es un buen ejemplo de dónde deberías usar un buen bucle antiguo. Si bien Files.lines() proporciona una secuencia secuencial, las secuencias pueden producirse y procesarse fuera de orden, por lo que insertar contadores y confiar en su orden es un mal hábito. Si todavía desea hacerlo, recuerde que en cualquier lugar que pueda usar un lambda puede usar una clase anónima completa. Las clases anónimas son clases normales, y como tales pueden tener estado.

Así que en tu ejemplo podrías hacer esto:

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


Puedes usar un AtomicInteger como un contador final mutable.

public void test() throws IOException { // Make sure the writer closes. try (FileWriter writer = new FileWriter("OutFile.txt") ) { // Use AtomicInteger as a mutable line count. final AtomicInteger count = new AtomicInteger(); // Make sure the stream closes. try (Stream<String> lines = Files.lines(Paths.get("InFile.txt"))) { lines.forEach(line -> { try { // Annotate with line number. writer.write(count.incrementAndGet() + " # " + line + System.lineSeparator()); } catch (Exception e) { e.printStackTrace(); } } ); } } }