En Java 8 tenemos la clase Stream <T> , que curiosamente tiene un método
Iterator<T> iterator()
Por lo tanto, es de esperar que implemente la interfaz Iterable <T> , que requiere exactamente este método, pero ese no es el caso.
Cuando quiero iterar sobre un Stream usando un bucle foreach, tengo que hacer algo como
public static Iterable<T> getIterable(Stream<T> s) {
return new Iterable<T> {
@Override
public Iterator<T> iterator() {
return s.iterator();
}
};
}
for (T element : getIterable(s)) { ... }
¿Me estoy perdiendo de algo?
java
java-8
java-stream
iterable
roim
fuente
fuente

Streama las API heredadas que esperaIterablegetIterable()quereturn s::iterator;for (T element : stream::iterator), por lo que aún preferiría que Stream también implementaraIterableo un métodotoIterable().Respuestas:
La gente ya ha preguntado lo mismo en la lista de correo ☺. La razón principal es que Iterable también tiene una semántica repetible, mientras que Stream no lo es.
fuente
Iterablesobre siiteratordebería o no ser invocable varias veces. Eso es algo que deberían poner allí. Esto parece ser más una práctica estándar que una especificación formal.Para convertir un
Streama unIterable, puedes hacerPara pasar
Streama un método que esperaIterable,simplemente
sin embargo, probablemente se ve divertido; podría ser mejor ser un poco más explícito
fuente
for(X x : (Iterable<X>)stream::iterator), aunque se ve feo. Realmente, toda la situación es simplemente absurda.IntStream.range(0,N).forEach(System.out::println)stream::iteratorystream.iterator(), eso hace que el primero sea aceptable para unIterablepero no el segundo?Iterablees una interfaz funcional, por lo que pasar una función que la implemente es suficiente.Me gustaría señalar que
StreamEximplementaIterable(yStream), así como una gran cantidad de otras funcionalidades inmensamente increíbles que faltanStream.fuente
Puede usar una secuencia en un
forbucle de la siguiente manera:(Ejecute este fragmento aquí )
(Esto utiliza una conversión de interfaz funcional Java 8).
(Esto está cubierto en algunos de los comentarios anteriores (por ejemplo, Aleksandr Dubinsky ), pero quería sacarlo en una respuesta para hacerlo más visible).
fuente
kennytm describió por qué no es seguro tratar un
Streamcomo unIterable, y Zhong Yu ofreció una solución alternativa que permite usar unStreamcomo enIterable, aunque de manera insegura. Es posible obtener lo mejor de ambos mundos: un reutilizableIterablede unoStreamque cumpla con todas las garantías hechas por laIterableespecificación.Nota:
SomeTypeno es un parámetro de tipo aquí; debe reemplazarlo con un tipo adecuado (por ejemplo,String) o recurrir a la reflexiónHay una gran desventaja:
Los beneficios de la iteración perezosa se perderán. Si planeaba iterar inmediatamente sobre todos los valores en el hilo actual, cualquier sobrecarga será insignificante. Sin embargo, si planeaba iterar solo parcialmente o en un hilo diferente, esta iteración inmediata y completa podría tener consecuencias no deseadas.
La gran ventaja, por supuesto, es que puede reutilizar
Iterable, mientras(Iterable<SomeType>) stream::iteratorque solo permitiría un solo uso. Si el código de recepción iterará en la colección varias veces, esto no solo es necesario, sino que probablemente sea beneficioso para el rendimiento.fuente
Stream.toArray()devuelve una matriz, no unIterable, por lo que este código aún no se compila. pero puede ser un error en eclipse, ya que IntelliJ parece compilarloStreamno implementaIterable. La comprensión general deIterablees todo lo que se puede repetir, a menudo una y otra vez.Streampuede no ser rejugableLa única solución que se me ocurre, en la que también se puede reproducir un iterable basado en una secuencia, es volver a crear la secuencia. Estoy usando un
Suppliersiguiente para crear una nueva instancia de transmisión, cada vez que se crea un nuevo iterador.fuente
Si no le importa usar bibliotecas de terceros, cyclops-react define un Stream que implementa Stream e Iterable y que también se puede volver a reproducir (resolviendo el problema descrito por kennytm ).
o: -
[Divulgación Soy el desarrollador principal de cyclops-react]
fuente
No es perfecto, pero funcionará:
No es perfecto, ya que se ha podido recuperar todos los elementos de la corriente y ponerlos en que
List, lo que no es exactamente lo queIterableyStreamestán a punto. Se supone que son flojos .fuente
Puede iterar sobre todos los archivos en una carpeta usando
Stream<Path>así:fuente