J'ai lu que les vecteurs ne sont pas des seqs, mais que les listes le sont. Je ne sais pas quelle est la justification de l'utilisation de l'un sur l'autre. Il semble que les vecteurs soient les plus utilisés, mais y a-t-il une raison à cela?
J'ai lu que les vecteurs ne sont pas des seqs, mais que les listes le sont. Je ne sais pas quelle est la justification de l'utilisation de l'un sur l'autre. Il semble que les vecteurs soient les plus utilisés, mais y a-t-il une raison à cela?
Réponses:
Encore une fois, il semble que j'ai répondu à ma propre question en m'impatientant et en la posant dans #clojure sur Freenode. Nous vous encourageons à répondre à vos propres questions sur Stackoverflow.com: D
J'ai eu une brève discussion avec Rich Hickey, et en voici l'essentiel.
[12:21] <Raynes> Vectors aren't seqs, right?
[12:21] <rhickey> Raynes: no, but they are sequential
[12:21] <rhickey> ,(sequential? [1 2 3])
[12:21] <clojurebot> true
[12:22] <Raynes> When would you want to use a list over a vector?
[12:22] <rhickey> when generating code, when generating back-to-front
[12:23] <rhickey> not too often in Clojure
Si vous avez beaucoup fait de la programmation Java et que vous êtes familier avec le framework de collecte Java, pensez à des listes comme LinkedList
et à des vecteurs comme ArrayList
. Vous pouvez donc à peu près choisir les conteneurs de la même manière.
Pour plus de précision: si vous avez l'intention d'ajouter beaucoup d'éléments individuellement au début ou à l'arrière de la séquence, une liste chaînée est bien meilleure qu'un vecteur, car les éléments n'ont pas besoin d'être mélangés à chaque fois. Cependant, si vous souhaitez accéder fréquemment à des éléments spécifiques (pas près de l'avant ou de l'arrière de la liste) (c.-à-d. Accès aléatoire), vous voudrez utiliser vector.
À propos, les vecteurs peuvent facilement être transformés en séquences.
user=> (def v (vector 1 2 3))
#'user/v
user=> v
[1 2 3]
user=> (seq v)
(1 2 3)
user=> (rseq v)
(3 2 1)
ArrayList
sans, effectivement, ArrayDeque
vous réimplémenter .
Les vecteurs ont des temps d'accès aléatoire O (1), mais ils doivent être préalloués. Les listes peuvent être étendues dynamiquement, mais l'accès à un élément aléatoire est O (n).
Quand utiliser un vecteur:
Quand utiliser une liste:
~O(1)
, pour ceux à qui cette explication des coûts pourrait être utile - stackoverflow.com/questions/200384/constant-amortized-time
juste un petit mot:
"J'ai lu que les vecteurs ne sont pas des séquences, mais les listes le sont."
les séquences sont plus génériques que les listes ou les vecteurs (ou les cartes ou les ensembles).
Il est malheureux que le REPL imprime les listes et les séquences de la même manière, car cela donne vraiment l'impression que les listes sont des séquences même si elles sont différentes. la fonction (seq) créera une séquence à partir d'un grand nombre de choses différentes, y compris des listes, et vous pourrez ensuite alimenter cette seq à l'une des pléthore de fonctions qui font des choses intéressantes avec des seqs.
user> (class (list 1 2 3))
clojure.lang.PersistentList
user> (class (seq (list 1 2 3)))
clojure.lang.PersistentList
user> (class (seq [1 2 3]))
clojure.lang.PersistentVector$ChunkedSeq
Sec a un raccourci qui retourne son argument s'il s'agit déjà d'un seq:
user> (let [alist (list 1 2 3)] (identical? alist (seq alist)))
true
user> (identical? (list 1 2 3) (seq (list 1 2 3)))
false
static public ISeq seq(Object coll){
if(coll instanceof ASeq)
return (ASeq) coll;
else if(coll instanceof LazySeq)
return ((LazySeq) coll).seq();
else
return seqFrom(coll);
}
les listes sont des séquences, bien que d'autres choses le soient également, et toutes les séquences ne sont pas des listes.
class
au lieu de class?
?
clojure.lang.PersistentList
me reviennent . Je suppose que vous vouliez écrire class
pas class?
.
class
renvoie la même PersistentList pour les deux expressions que vous avez mentionnées, cela implique que les séquences et les listes sont en effet exactement la même chose?