Ich habe gelesen, dass Vektoren keine Seqs sind, sondern Listen. Ich bin mir nicht sicher, was der Grund dafür ist, einen über den anderen zu verwenden. Es scheint, dass Vektoren am häufigsten verwendet werden, aber gibt es einen Grund dafür?
Ich habe gelesen, dass Vektoren keine Seqs sind, sondern Listen. Ich bin mir nicht sicher, was der Grund dafür ist, einen über den anderen zu verwenden. Es scheint, dass Vektoren am häufigsten verwendet werden, aber gibt es einen Grund dafür?
Antworten:
Wieder einmal scheint es, als hätte ich meine eigene Frage beantwortet, indem ich ungeduldig wurde und sie in #clojure auf Freenode gestellt habe. Auf Stackoverflow.com wird empfohlen, Ihre eigenen Fragen zu beantworten: D.
Ich hatte eine kurze Diskussion mit Rich Hickey, und hier ist der Kern davon.
[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
Wenn Sie viel mit Java programmiert haben und mit dem Java-Sammlungsframework vertraut sind, denken Sie an Listen wie LinkedList
und Vektoren wieArrayList
. Sie können also Container auf die gleiche Weise auswählen.
Zur weiteren Verdeutlichung: Wenn Sie Elemente einzeln einzeln an der Vorder- oder Rückseite der Sequenz hinzufügen möchten, ist eine verknüpfte Liste viel besser als ein Vektor, da die Elemente nicht jedes Mal gemischt werden müssen. Wenn Sie jedoch häufig auf bestimmte Elemente zugreifen möchten (nicht in der Nähe der Vorder- oder Rückseite der Liste) (z. B. Direktzugriff), sollten Sie den Vektor verwenden.
Vektoren können übrigens leicht in Seqs umgewandelt werden.
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
implementieren oder ohne sich selbst effektiv neu zu implementieren ArrayDeque
.
Vektoren haben O (1) zufällige Zugriffszeiten, müssen jedoch vorab zugeordnet werden. Listen können dynamisch erweitert werden, aber der Zugriff auf ein zufälliges Element ist O (n).
Wann wird ein Vektor verwendet?
Wann man eine Liste verwendet:
~O(1)
, für diejenigen, für die diese Kostenerklärung hilfreich sein könnte - stackoverflow.com/questions/200384/constant-amortized-time
nur eine kurze Randnotiz:
"Ich habe gelesen, dass Vektoren keine Seqs sind, sondern Listen."
Sequenzen sind allgemeiner als Listen oder Vektoren (oder Karten oder Mengen).
Es ist bedauerlich, dass die REPL Listen und Sequenzen gleich druckt, weil es wirklich so aussieht, als wären Listen Sequenzen, obwohl sie unterschiedlich sind. Die (seq) -Funktion erstellt eine Sequenz aus vielen verschiedenen Dingen, einschließlich Listen, und Sie können diese Sequenz dann jeder der zahlreichen Funktionen zuführen, die mit seqs raffinierte Dinge tun.
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 hat eine Verknüpfung, die ihr Argument zurückgibt, wenn es bereits eine Sequenz ist:
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);
}
Listen sind Sequenzen, obwohl es auch andere Dinge sind, und nicht alle Sequenzen sind Listen.
class
statt class?
?
clojure.lang.PersistentList
mir nicht sicher, ob sich Ihr Beispiel nach Clojure-Updates geändert hat (ich glaube, ich bin auf 1.5), aber beide Beispiele kehren für mich zurück. Ich gehe davon aus, dass du class
nicht schreiben wolltest class?
.
class
für beide von Ihnen erwähnten Ausdrücke dieselbe PersistentList zurückgegeben wird, bedeutet dies, dass Sequenzen und Listen tatsächlich genau dasselbe sind.