Collections 什么';Clojure中序列和集合的区别是什么

Collections 什么';Clojure中序列和集合的区别是什么,collections,clojure,abstraction,Collections,Clojure,Abstraction,我是一名Java程序员,是Clojure的新手。从不同的地方,我看到序列和集合在不同的情况下使用。然而,我不知道他们之间的确切区别是什么 例如: 1) 在Clojure的文件中: 如您所见,在描述Seq接口时,前两个函数(first/rest)使用coll,这似乎表明这是一个集合,而cons函数使用Seq,这似乎表明这是一个序列 2) 有称为coll?和seq?的函数可用于测试值是集合还是序列。很明显,收集和顺序是不同的 3) Clojure关于“”的文档中说: 因为集合支持seq函数,所以所有

我是一名Java程序员,是Clojure的新手。从不同的地方,我看到序列和集合在不同的情况下使用。然而,我不知道他们之间的确切区别是什么

例如:

1) 在Clojure的文件中:

如您所见,在描述Seq接口时,前两个函数(first/rest)使用
coll
,这似乎表明这是一个集合,而
cons
函数使用
Seq
,这似乎表明这是一个序列

2) 有称为
coll?
seq?
的函数可用于测试值是集合还是序列。很明显,收集和顺序是不同的

3) Clojure关于“”的文档中说:

因为集合支持seq函数,所以所有序列 函数可以与任何集合一起使用

这是否意味着所有集合都是序列

(coll? [1 2 3]) ; => true 
(seq? [1 2 3]) ; => false
上面的代码告诉我情况并非如此,因为
[1 2 3]
是一个集合,但不是序列


我认为这对Clojure来说是一个非常基本的问题,但我无法找到一个地方来清楚地解释它们的区别是什么,在不同的情况下应该使用哪一个。欢迎发表任何评论。

任何支持核心
第一
其余
功能的对象都是
序列

许多对象满足此接口,每个Clojure集合都提供至少一种seq对象,用于使用
seq
函数遍历其内容

因此:

您还可以从
映射创建序列对象

user> (seq {:a 1 :b 2})
    ([:a 1] [:b 2])
这就是为什么您可以在
映射上使用
过滤器
映射
for
,等等

因此,可以将许多类似集合的对象视为序列

这也是为什么许多序列处理函数,如输入上的
filter
call
seq

 (defn filter
  "Returns a lazy sequence of the items in coll for which
  (pred item) returns true. pred must be free of side-effects."
  {:added "1.0"
   :static true}
  ([pred coll]
   (lazy-seq
      (when-let [s (seq coll)]
如果您调用
(filter pred 5)

您可以看到,
seq
调用是该对象是否为序列验证的关键


如果你想更深入一点的话,大部分内容都在第5章中。

每个序列都是一个集合,但不是每个集合都是一个序列

seq
函数可以将集合转换为序列。例如,对于地图,您可以获得其条目列表。该条目列表与地图本身不同。

用于:

如果x实现ISeq,则返回true

用于:

如果x实现IPersistentCollection,则返回true

我在Clojure源代码中发现了IPersistentCollection的扩展,正如Rörd所说,每个序列都是一个集合。

作者以一种真正可以理解的方式总结了它:

集合抽象与序列密切相关
抽象。Clojure的所有核心数据结构-向量、地图、, 列表和集合-参与两种抽象

抽象的不同之处在于序列抽象是“关于” 在收集抽象完成时单独对成员进行操作 “关于”整个数据结构。例如,集合 函数
count
empty?
every?
与任何个人无关 元素;它们是关于整体的


以下几点有助于理解收集序列之间的区别

  • “Collection”和“Sequence”是抽象概念,不是可以从给定值确定的属性

  • 收藏是价值的袋子

  • Sequence是一种数据结构(集合的子集),预期以顺序(线性)方式访问

  • 下图最好地描述了它们之间的关系:


    你可以阅读更多有关它的内容。

    我刚刚阅读了《Clojure之乐》的第5章-“收藏类型”,这有点让人困惑(即,该书的下一版本需要审查)。在第5章第86页,有一个表格我并不完全满意:

    这是我的观点(经过一个月的思考后,我回到这一点上,完全更新了)

    收集 这是一个“东西”,是其他东西的集合

    这基于函数
    coll?

    • 可以使用函数
      coll?
      对此进行测试
    • 相反地,
      coll?
      返回true的任何内容都是一个集合
    coll?
    docstring说明:

    如果x实现
    IPersistentCollection

    将集合分为三个独立类的事物。不同阶级的事物永远不平等

    • 使用
      (map?foo)
      • Map(两个实际实现,行为略有不同)
      • 分类地图。注意:
        (顺序)(排序映射:A1)
        ;=>错误
    • 使用
      (set?foo)
      • 设置
      • 排序集。注意:
        (顺序)(排序集:a:b))
        ;=>错误
    • 使用
      (Sequential?foo)
      • 名单
      • 载体
      • 排队
      • Seq:
        (顺序)(Seq[1 2 3])
        ;=>正确
      • 惰性序列:
        (顺序)(惰性序列(序列[1 2 3]))
        ;=>true
    Java互操作的内容不在此范围内:

    • (coll?(到数组[1 2 3])
      ;=>错误
    • (map?(doto(新java.util.HashMap)(.put“a”1)(.put“b”2)))
      ;=>false
    顺序收集(一条“链”) 它是一个“东西”,一个集合,按照特定的、稳定的顺序存放其他东西

    这是基于函数
    sequential?

    • 函数
      顺序?
      user> (seq {:a 1 :b 2})
          ([:a 1] [:b 2])
      
       (defn filter
        "Returns a lazy sequence of the items in coll for which
        (pred item) returns true. pred must be free of side-effects."
        {:added "1.0"
         :static true}
        ([pred coll]
         (lazy-seq
            (when-let [s (seq coll)]
      
        Don't know how to create ISeq from: java.lang.Long
                        RT.java:505 clojure.lang.RT.seqFrom
                        RT.java:486 clojure.lang.RT.seq
                       core.clj:133 clojure.core/seq
                      core.clj:2523 clojure.core/filter[fn]
      
      (def empty-seq (rest (seq [:x])))
      
      (type? empty-seq)                 ;=> clojure.lang.PersistentList$EmptyList
      
      (nil? empty-seq)                  ;=> false ... empty seq is not nil
      (some? empty-seq)                 ;=> true ("true if x is not nil, false otherwise.")
      
      (first empty-seq)                 ;=> nil   ... first of empty seq is nil ("does not exist"); beware confusing this with a nil in a nonempty list!
      (next empty-seq)                  ;=> nil   ... "next" of empty seq is nil
      (rest empty-seq)                  ;=> ()    ... "rest" of empty seq is the empty seq
         (type (rest empty-seq))        ;=> clojure.lang.PersistentList$EmptyList
         (seq? (rest empty-seq))        ;=> true
         (= (rest empty-seq) empty-seq) ;=> true
      
      (count empty-seq)                 ;=> 0
      (empty? empty-seq)                ;=> true