在Clojure中,我应该何时在列表中使用向量,反之亦然?

时间:2009-07-18 16:41:26

标签: list vector clojure sequences

我读过Vector不是seqs,但列表是。我不确定使用一个在另一个上的理由是什么。似乎向量使用最多,但是有这个原因吗?

5 个答案:

答案 0 :(得分:106)

再一次,似乎我已经回答了我自己的问题,因为他不耐烦地在Freenode的#clojure上提问。 Stackoverflow.com鼓励回答您自己的问题:D

我与Rich Hickey进行了快速讨论,这是它的要点。

[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

答案 1 :(得分:80)

如果您已经完成了Java编程并且熟悉Java集合框架,请考虑像LinkedList这样的列表和ArrayList之类的向量。所以你几乎可以用同样的方式选择容器。

进一步澄清:如果您打算在序列的前面或后面单独添加项目,链接列表比矢量要好得多,因为每次都不需要对项目进行洗牌。但是,如果您想要经常访问特定元素(不在列表的前面或后面)(即随机访问),您将需要使用向量。

顺便说一下,矢量很容易变成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)

答案 2 :(得分:37)

向量具有O(1)个随机访问时间,但必须预先分配它们。列表可以动态扩展,但访问随机元素是O(n)。

答案 3 :(得分:28)

何时使用矢量:

  • 索引访问性能 - 索引访问成本约为O(1),列表为O(n)
  • 追加 - 与conj是~O(1)
  • 方便的符号 - 我发现在任何一种文字列表工作的情况下输入和阅读[1 2 3]比文字列表更容易(1 2 3)。

何时使用列表:

  • 当你想以序列形式访问它时(因为列表直接支持seq而不必分配新对象)
  • 预先添加 - 使用cons或优选conj添加到列表的开头是O(1)

答案 4 :(得分:13)

只是一个简短的说明:
    

"I read that Vectors are not seqs, but Lists are." 

序列比列表或矢量(或地图或集合)更通用 不幸的是, REPL打印列表和序列相同因为它确实使列表看起来像序列即使它们是不同的。 (seq)函数将从许多不同的事物(包括列表)中生成一个序列,然后您可以将该seq提供给任何使用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有一个快捷方式,如果它已经是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);
}

列表是序列,但其他内容也是如此,并非所有序列都是列表。

相关问题