Premièrement, ils sont tous non stricts . Cela a une signification mathématique particulière liée aux fonctions, mais signifie essentiellement qu'elles sont calculées à la demande plutôt qu'à l'avance.
Stream
est en effet une liste paresseuse. En fait, dans Scala, a Stream
est un List
dont tail
est a lazy val
. Une fois calculée, une valeur reste calculée et est réutilisée. Ou, comme vous le dites, les valeurs sont mises en cache.
An Iterator
ne peut être utilisé qu'une seule fois car il s'agit d'un pointeur de parcours vers une collection et non d'une collection en soi. Ce qui le rend spécial dans Scala est le fait que vous pouvez appliquer une transformation telle que map
et filter
et simplement en obtenir une nouvelle Iterator
qui n'appliquera ces transformations que lorsque vous demanderez l'élément suivant.
Scala avait l'habitude de fournir des itérateurs qui pouvaient être réinitialisés, mais c'est très difficile à supporter d'une manière générale, et ils n'ont pas fait la version 2.8.0.
Les vues sont censées être affichées comme une vue de base de données. C'est une série de transformation que l'on applique à une collection pour produire une collection «virtuelle». Comme vous l'avez dit, toutes les transformations sont réappliquées chaque fois que vous devez en extraire des éléments.
Les deux Iterator
vues ont d'excellentes caractéristiques de mémoire. Stream
c'est bien, mais, en Scala, son principal avantage est d'écrire des séquences infinies (en particulier des séquences définies de manière récursive). On peut cependant éviter de garder tout le Stream
en mémoire, en s'assurant de ne pas garder une référence à son head
(par exemple, en utilisant def
au lieu de val
pour définir le Stream
).
En raison des pénalités encourues par les vues, il convient généralement de force
le conserver après l'application des transformations, ou de le conserver en tant que vue si seuls quelques éléments sont censés être extraits, par rapport à la taille totale de la vue.