384 votes

Différence entre une Seq et une liste en Scala

J'ai vu dans de nombreux exemples que parfois une Seq est utilisée, alors que d'autres fois c'est la Liste...

Y a-t-il une différence, si ce n'est que le premier est un type Scala et que la liste vient de Java ?

504voto

Daniel C. Sobral Points 159554

En termes de Java, l'approche de Scala Seq serait celle de Java List et de Scala List serait celle de Java LinkedList .

Notez que Seq est un trait ce qui est équivalent à la méthode Java interface mais avec l'équivalent des méthodes des défenseurs en devenir. La méthode Scala List est une classe abstraite qui est étendue par Nil et :: qui sont les implémentations concrètes de List .

Donc, là où Java List est un interface de Scala List est une mise en œuvre.

En outre, l'outil de Scala List 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 seulement que le nouvel objet ne peut pas être modifié, mais vous pouvez toujours modifier l'ancien et, par conséquent, l'objet "en lecture seule").

L'approche de Scala List est hautement optimisé par le compilateur et les bibliothèques, et c'est un type de données fondamental en programmation fonctionnelle. Cependant, il a des limites et il est inadéquat pour la programmation parallèle. De nos jours, Vector est un meilleur choix que List mais l'habitude est difficile à perdre.

Seq est une bonne généralisation pour les séquences, donc si vous programmez pour des interfaces, vous devriez l'utiliser. Notez qu'il y en a en fait trois : collection.Seq , collection.mutable.Seq et collection.immutable.Seq et c'est cette dernière qui est importée par "défaut" dans le champ d'application.

Il y a aussi GenSeq et ParSeq . Ces dernières méthodes fonctionnent en parallèle dans la mesure du possible, tandis que la première est parente des deux méthodes suivantes Seq et ParSeq étant une généralisation appropriée pour les cas où le parallélisme d'un code n'a pas d'importance. Ils sont tous les deux relativement récents, donc les gens ne les utilisent pas encore beaucoup.

3 votes

RE "Java n'a pas d'équivalent aux collections immuables" bien que String n'est pas une collection, c'est un exemple de classes immuables familières aux programmeurs Java.

20 votes

@huynhjl Ce n'est pas le sujet. Je faisais un parallèle entre ce qui existe en Java et ce qui existe en Scala, et il n'y a tout simplement pas de concept de collections mutables/immuables en Java.

1 votes

ParSeq est probablement peu utilisé car ses cas d'utilisation sont limités par la loi d'Amdahl - votre gain de vitesse grâce au parallélisme est limité si le temps d'exécution est dominé par ses bits séquentiels. A utiliser avec précaution.

134voto

Ceasar Bautista Points 1006

A Seq est un Iterable dont l'ordre des éléments est défini. Les séquences fournissent une méthode apply() pour l'indexation, allant de 0 à la longueur de la séquence. Seq possède de nombreuses sous-classes, notamment Queue, Range, List, Stack et LinkedList.

A Liste est une Seq qui est implémentée comme une liste chaînée immuable. Il est préférable de l'utiliser dans les cas de modèles d'accès LIFO (last-in first-out).

Voici la hiérarchie complète des classes de collection de la FAQ Scala :

enter image description here

38voto

Akavall Points 7357

Seq est un trait qui List met en œuvre.

Si vous définissez votre conteneur comme Seq vous pouvez utiliser n'importe quel conteneur qui implémente la fonction Seq trait.

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)

C'est juste un raccourci 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 prend par défaut la forme suivante List .

19voto

zakelfassi Points 622

En Scala, une Liste hérite de Seq, mais implémente Produit ; voici la définition correcte de Liste :

sealed abstract class List[+A] extends AbstractSeq[A] with Product with ...

[Note : le site réel définition est un peu plus complexe, afin de s'intégrer et d'utiliser le cadre de collecte très puissant de Scala].

3voto

Profiterole Points 111

Comme l'a dit @daniel-c-sobral, List étend le trait Seq et est une classe abstraite implémentée par scala.collection.immutable.$colon$colon (ou :: pour faire court), mais au-delà des détails techniques, gardez à l'esprit que la plupart des listes et seqs que nous utilisons sont initialisés sous la forme de Seq(1, 2, 3) ou List(1, 2, 3) qui renvoient tous deux scala.collection.immutable.$colon$colon et 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épendre vous pouvez utiliser :: de List que je trouve redondant avec +: de Seq et je m'en tiens personnellement à Seq par défaut.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X