Respuestas:
Una vez más, parece que he respondido mi propia pregunta poniéndome impaciente y preguntándola en #clojure en Freenode. Se recomienda responder a sus propias preguntas en Stackoverflow.com: D
Tuve una discusión rápida con Rich Hickey, y aquí está lo esencial.
[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 ha hecho mucha programación en Java y está familiarizado con el marco de recopilación de Java, piense en listas como LinkedList
y vectores similares ArrayList
. Así que puedes elegir contenedores de la misma manera.
Para una mayor aclaración: si tiene la intención de agregar elementos individualmente al principio o al final de la secuencia, una lista vinculada es mucho mejor que un vector, ya que los elementos no necesitan ser barajados cada vez. Sin embargo, si desea llegar a elementos específicos (no cerca del frente o al final de la lista) con frecuencia (es decir, acceso aleatorio), querrá usar el vector.
Por cierto, los vectores se pueden convertir fácilmente en seqs.
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
sin, efectivamente, reimplementándose ArrayDeque
.
Los vectores tienen O (1) tiempos de acceso aleatorio, pero deben ser preasignados. Las listas se pueden extender dinámicamente, pero acceder a un elemento aleatorio es O (n).
Cuando usar un vector:
Cuándo usar una lista:
~O(1)
, para aquellos a quienes esta explicación de costos podría ser útil - stackoverflow.com/questions/200384/constant-amortized-time
solo una nota al margen rápida:
"Leí que los vectores no son seqs, pero las listas sí".
Las secuencias son más genéricas que las listas o los vectores (o los mapas o conjuntos).
Es desafortunado que REPL imprima listas y secuencias de la misma manera porque realmente hace que parezca que las listas son secuencias a pesar de que son diferentes. la función (seq) creará una secuencia de muchas cosas diferentes, incluidas listas, y luego puede alimentar esa seq a cualquiera de la gran cantidad de funciones que hacen cosas ingeniosas con 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 tiene un acceso directo que devuelve su argumento si ya es 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);
}
las listas son secuencias, aunque otras cosas también lo son, y no todas las secuencias son listas.
class
lugar de class?
?
clojure.lang.PersistentList
me son devueltos . Supongo que querías escribir class
no class?
.
class
devuelve la misma lista persistente para ambas expresiones que mencionó, ¿esto implica que las secuencias y las listas son exactamente lo mismo?