web-dev-qa-db-fra.com

Stream vs vues vs itérateurs

Quelles sont les différences entre les flux, les vues (SeqView) et les itérateurs dans scala? Voici ma compréhension:

  • Ce sont toutes des listes paresseuses.
  • Les flux mettent en cache les valeurs.
  • Les itérateurs ne peuvent être utilisés qu'une seule fois? Vous ne pouvez pas revenir au début et évaluer à nouveau la valeur?
  • Les valeurs de la vue ne sont pas mises en cache mais vous pouvez les évaluer encore et encore?

Donc, si je veux économiser de l'espace, dois-je utiliser des itérateurs (si je ne traverse plus la liste) ou des vues? Merci.

131
JWC

Tout d'abord, ils sont tous non stricts. Cela a une signification mathématique particulière liée aux fonctions, mais, fondamentalement, signifie qu'elles sont calculées à la demande plutôt qu'à l'avance.

Stream est en effet une liste paresseuse. En fait, dans Scala, un Stream est un List dont tail est un 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.

Un Iterator ne peut être utilisé qu'une seule fois car il s'agit d'un pointeur de traversée dans une collection, et non d'une collection en soi. Ce qui le rend spécial dans Scala est le fait que vous pouvez appliquer des transformations telles que map et filter et obtenir simplement un nouveau Iterator qui n'appliquera ces transformations que lorsque vous demanderez l'élément suivant.

Scala fournissait des itérateurs qui pouvaient être réinitialisés, mais c'est très difficile à prendre en charge de manière générale, et ils n'ont pas fait la version 2.8.0.

Les vues sont censées être vues comme une vue de base de données. C'est une série de transformations 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.

Iterator et les vues ont d'excellentes caractéristiques de mémoire. Stream est Nice, mais, dans Scala, son principal avantage est d'écrire des séquences infinies (en particulier des séquences définies récursivement). Un peut éviter de garder tout le Stream en mémoire, cependant, en vous assurant de ne pas garder de 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 le force après avoir appliqué les transformations, ou de le conserver en tant que vue si seuls quelques éléments devraient être récupérés, par rapport à la taille totale de la vue.

178
Daniel C. Sobral