Scala 中 Seq 和 List 之间的区别

Difference between a Seq and a List in Scala

提问人:opensas 提问时间:6/3/2012 最后编辑:Jonikopensas 更新时间:2/8/2023 访问量:194851

问:

我在许多示例中看到,有时使用序列,而有时是列表......

除了前者是 Scala 类型和来自 Java 的 List 之外,有什么区别吗?

列出 Scala 集合 序列

评论


答:

18赞 zakelfassi 6/3/2012 #1

在 Scala 中,List 继承自 Seq,但实现了 Product;以下是 List 的正确定义:

sealed abstract class List[+A] extends AbstractSeq[A] with Product with ...

[注意:实际定义稍微复杂一些,以便适应和利用 Scala 非常强大的集合框架。

496赞 Daniel C. Sobral 6/3/2012 #2

用 Java 术语来说,Scala 就是 Java 的,而 Scala 就是 Java 的。SeqListListLinkedList

请注意,这是一个 ,它类似于 Java 的 ,但相当于新兴的防御方法。Scala 是一个抽象类,由 和 扩展,它们是 的具体实现。SeqtraitinterfaceListNil::List

所以,Java 是一个,Scala 是一个实现。ListinterfaceList

除此之外,Scala 是不可变的,但 .事实上,Java 没有等同于不可变集合的东西(只读的东西只能保证新对象不能被更改,但你仍然可以更改旧对象,因此可以更改“只读”对象)。ListLinkedList

Scala 通过编译器和库进行了高度优化,它是函数式编程中的基本数据类型。但是,它有局限性,不足以进行并行编程。如今,是比 更好的选择,但习惯很难改掉。ListVectorList

Seq对于序列来说,这是一个很好的泛化,所以如果你编程到接口,你应该使用它。请注意,实际上有三个:、 和 ,后者是导入作用域的“默认”。collection.Seqcollection.mutable.Seqcollection.immutable.Seq

还有 和 .后一种方法在可能的情况下并行运行,而前者是 和 的父级,是 不关心代码并行性的合适泛化。它们都是相对较新的,所以人们不会经常使用它们。GenSeqParSeqSeqParSeq

评论

3赞 huynhjl 6/3/2012
RE “Java has no equivalent to immutable collections”,虽然它不是一个集合,但它是 Java 程序员熟悉的不可变类的一个例子。String
19赞 Daniel C. Sobral 6/3/2012
@huynhjl 这无关紧要。我把 Java 中存在的东西和 Scala 中存在的东西相提并论,Java 中没有任何可变/不可变集合的概念。
2赞 jbx 11/15/2013
Java 实际上具有不可变集合的等价物。它不是那么“广告”,但它就在那里,当你大量使用仿制药时,你可能会因此而遇到一些。要在 Java 中创建一个不可变列表,请使用 Collections.unmodifiableList(),同样,还有其他方法用于 Sets、Maps 等 docs.oracle.com/javase/6/docs/api/java/util/UnsupportedOperationException
32赞 Daniel C. Sobral 11/15/2013
@jbx 不对。如果使用这些方法,则会得到一个对象,该对象会在修改它的方法上引发异常,而不是不可变对象。如果原始对象在不可修改对象创建后被修改,则不可修改对象将反映这一点。所以,不可修改,是的,不可变的,不。
4赞 Daniel C. Sobral 11/15/2013
@jbx 接收方法不能保留对它所接收集合的引用,并假设它永远不会改变,而且标准 Java 库中没有类型可以保证这一点——这就是不可变性。因此,例如,这种接收方法不能保证螺纹安全。这甚至没有触及不变性所实现的持久性。没有这一切,它就不能被称为“等价物”。
130赞 Ceasar 4/18/2017 #3

Seq 是具有定义元素顺序的 Iterable。序列提供了一种索引方法,范围从 0 到序列的长度。Seq 有许多子类,包括 Queue、Range、List、Stack 和 LinkedList。apply()

列表是作为不可变链表实现的序列。它最适合用于后进先出 (LIFO) 访问模式的情况。

以下是 Scala FAQ 中的完整集合类层次结构:

enter image description here

评论

5赞 Peter Krauss 10/5/2019
Array(和 ArrayBuffer)在哪里?它不是那种可迭代的
1赞 Topa 1/29/2022
这个答案显示 Array
0赞 Ricardo 7/22/2022
如果您对肯定式感到好奇,最好在后进先出 (LIFO) 访问模式的情况下使用它,请将使用和操作视为 O(1) 与 OR ,即列表中元素数的 O(n)。prepend()head()append()last()
36赞 Akavall 6/28/2017 #4

Seq是实现的特征。List

如果将容器定义为 ,则可以使用任何实现 trait 的容器。SeqSeq

scala> def sumUp(s: Seq[Int]): Int = { s.sum }
sumUp: (s: Seq[Int])Int

scala> sumUp(List(1,2,3))
res41: Int = 6

scala> sumUp(Vector(1,2,3))
res42: Int = 6

scala> sumUp(Seq(1,2,3))
res44: Int = 6

请注意,

scala> val a = Seq(1,2,3)
a: Seq[Int] = List(1, 2, 3)

只是以下的简写:

scala> val a: Seq[Int] = List(1,2,3)
a: Seq[Int] = List(1, 2, 3)

如果未指定容器类型,则基础数据结构默认为 。List

2赞 Profiterole 8/12/2019 #5

正如 @daniel-c-sobral 所说,List 扩展了特征 Seq,并且是由(或简称)实现的抽象类,但撇开技术细节不谈,请注意,我们使用的大多数列表和 seq 都是以 或 的形式初始化的,两者都返回,因此可以这样写:scala.collection.immutable.$colon$colon::Seq(1, 2, 3)List(1, 2, 3)scala.collection.immutable.$colon$colon

var x: scala.collection.immutable.$colon$colon[Int] = null
x = Seq(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]
x = List(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]

因此,我认为唯一重要的是您要公开的方法,例如,在前面,您可以使用 from List 使用,我发现 from Seq 是多余的,我个人默认坚持使用 Seq。::+: