J'ai vu dans de nombreux exemples que parfois une Seq est utilisée, alors que d'autres fois est la liste ...
Existe-t-il une différence, si ce n'est que l'ancien est un type Scala et la liste provenant de Java?
En termes Java, le Seq
de Scala serait le List
de Java, et le List
de Scala serait le LinkedList
de Java.
Notez que Seq
est un trait
, ce qui équivaut à interface
de Java, mais avec l'équivalent des méthodes de défenseur montantes. List
de Scala est une classe abstraite étendue par Nil
et ::
, qui sont les implémentations concrètes de List
.
Donc, où List
de Java est un interface
, List
de Scala est une implémentation.
Au-delà, le List
de Scala est immuable, ce qui n'est pas le cas de LinkedList
. En fait, Java n’a pas d’équivalent aux collections immuables (la lecture seule garantit uniquement que le nouvel objet ne peut pas être modifié, mais vous pouvez toujours modifier l’ancien et, par conséquent, celui "lecture seule").
List
de Scala est hautement optimisé par le compilateur et les bibliothèques et constitue un type de données fondamental en programmation fonctionnelle. Cependant, il a des limites et est inadéquat pour la programmation parallèle. De nos jours, Vector
est un meilleur choix que List
, mais il est difficile de rompre l'habitude.
Seq
est une bonne généralisation pour les séquences, donc si vous programmez des interfaces, vous devriez l'utiliser. Notez qu'il y en a trois: collection.Seq
, collection.mutable.Seq
et collection.immutable.Seq
, et c'est ce dernier qui est "par défaut" importé dans scope.
Il y a aussi GenSeq
et ParSeq
. Ces dernières méthodes fonctionnent en parallèle autant que possible, tandis que la première est le parent de Seq
et ParSeq
, ce qui est une généralisation appropriée lorsque le parallélisme d'un code n'a pas d'importance. Ils sont tous deux relativement nouveaux, donc les gens ne les utilisent pas encore beaucoup.
Un Seq est un Iterable qui a un ordre défini d'éléments. Les séquences fournissent une méthode apply()
pour l'indexation, allant de 0 à la longueur de la séquence. Seq a de nombreuses sous-classes, notamment Queue, Range, List, Stack et LinkedList.
A List est une Seq implémentée en tant que liste chaînée immuable. Il est préférable de l'utiliser dans les cas avec des modèles d'accès dernier entré, premier sorti (LIFO).
Voici la hiérarchie complète des classes de collection de Scala FAQ :
En Scala, une liste hérite de Seq, mais implémente Product ; voici la définition correcte de List :
sealed abstract class List[+A] extends AbstractSeq[A] with Product with ...
[Remarque: la définition réelle est un peu plus complexe, afin de s'intégrer et d'utiliser le très cadre de collection puissant.]
Seq
est un trait que List
implémente.
Si vous définissez votre conteneur comme Seq
, vous pouvez utiliser n’importe quel conteneur qui implémente le trait Seq
.
scala> def sumUp(s: Seq[Int]): Int = { s.sum }
sumUp: (s: Seq[Int])Int
scala> sumUp(List(1,2,3))
res41: Int = 6
scala> sumUp(Vector(1,2,3))
res42: Int = 6
scala> sumUp(Seq(1,2,3))
res44: Int = 6
Notez que
scala> val a = Seq(1,2,3)
a: Seq[Int] = List(1, 2, 3)
Est juste un coup de main pour:
scala> val a: Seq[Int] = List(1,2,3)
a: Seq[Int] = List(1, 2, 3)
si le type de conteneur n'est pas spécifié, la structure de données sous-jacente est définie par défaut sur List
.
Comme @ daniel-c-sobral a dit, List étend le trait Seq et est une classe abstraite implémentée par scala.collection.immutable.$colon$colon
(ou ::
, en abrégé), mais les détails techniques mis à part, sachez que la plupart des listes et des séquences que nous utilisons sont initialisés sous la forme de Seq(1, 2, 3)
ou List(1, 2, 3)
qui retournent tous les deux scala.collection.immutable.$colon$colon
, on peut donc écrire:
var x: scala.collection.immutable.$colon$colon[Int] = null
x = Seq(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]
x = List(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]
En conséquence, je dirais que la seule chose qui compte, ce sont les méthodes que vous voulez exposer, par exemple pour préfixer, vous pouvez utiliser ::
de List que je trouve redondant avec +:
de Seq and I persévérez personnellement à Seq par défaut.