recorrer lista ejemplo java for-loop foreach java-8 java-stream

lista - Cómo iterar con foreach loop over java 8 stream



recorrer lista java 8 (4)

Stream no implementa Iterable, ni es una matriz, por lo que no es elegible para su uso en un bucle mejorado para. La razón por la que no implementa Iterable es porque es una estructura de datos de uso único. Cada vez que se llama a Iterable.iterator, se debe devolver un nuevo Iterador que cubra todos los elementos. El método iterador en Stream solo refleja el estado actual de Stream. Es efectivamente una vista diferente de la corriente.

Podría crear una clase que implemente Iterable envolviendo una secuencia para usar en el bucle for mejorado. Pero esta es una idea cuestionable ya que no se puede implementar realmente Iterable (como se describe anteriormente).

Supongamos que intentamos aplicar a java 8 stream una lambda que podría lanzar una excepción comprobada:

Stream<String> stream = Stream.of("1", "2", "3"); Writer writer = new FileWriter("example.txt"); stream.forEach(s -> writer.append(s)); // Unhandled exception: java.io.IOException

Esto no compilará.

Una solución es anidar la excepción marcada en RuntimeException pero complica el manejo posterior de las excepciones y es simplemente feo:

stream.forEach(s -> { try { writer.append(s); } catch (IOException e) { throw new RuntimeException(e); } });

Una solución alternativa podría ser convertir forEach funcional forEach a un loop foreach antiguo simple que sea más amigable para las excepciones verificadas.

Pero los enfoques ingenuos fallan:

for (String s : stream) { // for-each not applicable to expression type ''java.util.stream.Stream<java.lang.String>'' writer.append(s); } for (String s : stream.iterator()) { // foreach not applicable to type ''java.util.Iterator<java.lang.String>'' writer.append(s); }

Actualizar

Anteriormente se publicó un truco que responde a esta pregunta en ¿Por qué Stream <T> no implementa Iterable <T>? Como respuesta lateral que realmente no responde a esa pregunta en sí. Creo que esto no es suficiente para calificar esta pregunta como un duplicado de esa pregunta porque preguntan cosas diferentes.


También puedes hacerlo así:

Path inputPath = Paths.get("..."); Stream<Path> stream = Files.list(inputPath); for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext(); ) { Path path = iterator.next(); // ... }


loop bucle foreach requiere que se pueda pasar un Iterable .

Se puede lograr con clase anónima:

for (String s : new Iterable<String>() { @Override public Iterator<String> iterator() { return stream.iterator(); } }) { writer.append(s); }

Esto se puede simplificar con lambda porque Iterable es una interfaz funcional :

for (String s : (Iterable<String>) () -> stream.iterator()) { writer.append(s); }

Esto se puede convertir a referencia de método :

for (String s : (Iterable<String>) stream::iterator) { writer.append(s); }

La conversión explícita se puede evitar con la variable intermedia o el método param:

Iterable<String> iterable = stream::iterator; for (String s : iterable) { writer.append(s); }

También hay StreamEx biblioteca StreamEx en StreamEx Central que cuenta con flujos iterables y otras ventajas fuera de la caja.

Estas son algunas de las preguntas y enfoques más populares que brindan soluciones al manejo de excepciones verificadas en lambdas y flujos:

¿Función de Java 8 Lambda que lanza excepción?

Java 8: Lambda-Streams, filtro por método con excepción

¿Cómo puedo lanzar excepciones COMPROBADAS desde dentro de flujos de Java 8? (No envolverlo en excepciones sin marcar)

Java 8: manejo obligatorio de excepciones verificadas en expresiones lambda. ¿Por qué obligatorio, no opcional?

jOOλ Unchecked

Kotlin ;)


Escribí una extensión a la API de Stream que permite lanzar excepciones comprobadas.

Stream<String> stream = Stream.of("1", "2", "3"); Writer writer = new FileWriter("example.txt"); ThrowingStream.of(stream, IOException.class).forEach(writer::append);