web-dev-qa-db-fra.com

Différence entre une séquence et une liste dans Scala

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?

266
opensas

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.

358
Daniel C. Sobral

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 :

enter image description here

63
Ceasar Bautista

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.]

18
zakelfassi

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.

15
Akavall

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.

0
Profiterole