¿Cuáles son las diferencias entre Streams, Views (SeqView) e Iterators en scala? Este es mi entendimiento:
- Son todas listas perezosas.
- Las secuencias almacenan en caché los valores.
- ¿Los iteradores solo se pueden usar una vez? ¿No puede volver al principio y evaluar el valor nuevamente?
- Los valores de la vista no se almacenan en caché, pero puede evaluarlos una y otra vez.
Entonces, si quiero ahorrar espacio en el montón, ¿debo usar iteradores (si no voy a recorrer la lista nuevamente) o vistas? Gracias.
Respuestas:
Primero, todos son no estrictos . Eso tiene un significado matemático particular relacionado con las funciones, pero, básicamente, significa que se calculan a pedido en lugar de por adelantado.
Stream
es una lista perezosa de hecho. De hecho, en Scala, aStream
es unList
cuyotail
es alazy val
. Una vez calculado, un valor permanece calculado y se reutiliza. O, como usted dice, los valores se almacenan en caché.Un
Iterator
solo se puede usar una vez porque es un puntero transversal a una colección, y no una colección en sí misma. Lo que lo hace especial en Scala es el hecho de que se puede aplicar la transformación comomap
yfilter
y simplemente obtener una nuevaIterator
que sólo se aplicarán estas transformaciones cuando se pide el siguiente elemento.Scala solía proporcionar iteradores que podrían restablecerse, pero eso es muy difícil de soportar de manera general, y no hicieron la versión 2.8.0.
Las vistas están destinadas a ser vistas como una vista de base de datos. Es una serie de transformación que se aplica a una colección para producir una colección "virtual". Como dijiste, todas las transformaciones se vuelven a aplicar cada vez que necesitas extraer elementos de él.
Ambos
Iterator
y las vistas tienen excelentes características de memoria.Stream
es agradable, pero, en Scala, su principal beneficio es escribir secuencias infinitas (particularmente secuencias definidas recursivamente). Sin embargo, se puede evitar mantener todoStream
en la memoria, asegurándose de no mantener una referencia a suhead
(por ejemplo, al usar endef
lugar deval
para definir elStream
).Debido a las penalizaciones incurridas por las vistas, generalmente
force
se debe aplicar después de aplicar las transformaciones, o mantenerlo como una vista si se espera que solo se recuperen pocos elementos, en comparación con el tamaño total de la vista.fuente
Iterator
También es bastante útil para sondear el infinito, y generalmente los prefiero a las transmisiones siempre que sea posible. El beneficio real en las secuencias es que los valores a los que se accedió anteriormente se almacenan en caché, lo que es una gran ayuda cuando se trata de implementar algo como la secuencia de Fibonacci, que se define en términos de valores anteriores.