Scala中Seq和列表之间的区别


299

我在许多示例中看​​到有时使用Seq,而其他时候使用List ...

除了前一种是Scala类型和List来自Java外,还有什么区别吗?

Answers:


408

用Java术语来说,Scala Seq是Java List,而Scala List是Java LinkedList

请注意,它Seq是一个trait与Java等效的interface,但与即将出现的防御者方法等效。Scala List是由Nil和扩展的抽象类::,它们是的具体实现List

因此,在Java List是的地方interface,Scala List是实现的。

除此之外,Scala的List属性是不可变的,而不是LinkedList。实际上,Java不等同于不可变的集合(只读内容仅保证不能更改新对象,但是您仍然可以更改旧对象,因此也可以更改“只读”对象)。

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

Seq是对序列的一个很好的概括,因此,如果对接口进行编程,则应使用它。请注意,实际上它们共有三个:collection.Seqcollection.mutable.Seqcollection.immutable.Seq,而后者是导入到范围中的“默认”。

还有GenSeqParSeq。后面的方法在平行尽可能运行,而前者是父既SeqParSeq,是用于当的代码并行无所谓合适的概括。它们都是相对较新的引入,因此人们还不太使用它们。


3
RE “ Java没有等同于不可变的集合”,尽管String它不是集合,但它是Java程序员熟悉的不可变类的示例。
huynhjl 2012年

15
@huynhjl这不重要。我在Java中存在的内容和Scala中存在的内容之间进行了比较,而Java中没有任何可变/不可变集合的概念。
Daniel C. Sobral

2
Java实际上具有等同于不可变集合的功能。它不是那么“广为宣传”,而是在那里,当您大量使用泛型时,您可能会因此而遭受打击UnsupportedOperationException。要在Java中创建不可变列表,请使用Collections.unmodifiableList(),类似地,还有Set,Maps等其他方法。docs.oracle.com
javase/

27
@jbx不正确。如果使用这些方法,则会得到一个对象,该对象将在修改它的方法上引发异常,而不是不可变的对象。如果在创建了不可修改的对象之后修改了原始对象,则不可修改的对象将反映出来。因此,不可修改,是,不可变,否。
Daniel C. Sobral

3
@jbx接收方法无法保留对其接收到的集合的引用,并假定它永远不会更改,并且标准Java库中没有任何类型可以保证-这是不变的。因此,例如,该接收方法不能保证线程安全。而且这甚至都没有触及不可变性所带来的持久特性。没有所有这些,就不能称为“等效”。
Daniel C. Sobral

81

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

一个列表是作为不可改变的链表实现的序列。最好使用后进先出(LIFO)访问模式的情况。

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

在此处输入图片说明


2
数组(和ArrayBuffer)在哪里?这不是可迭代的
Peter Krauss

23

SeqList实现的特征。

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

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


18

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

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

[注:实际的定义,是一点点与和利用Scala的非常强大的集合框架的复杂一点,为了配合]


0

正如@ daniel-c-sobral所说,List扩展了特征Seq并是由scala.collection.immutable.$colon$colon(或::简称)实现的抽象类,但是除了技术方面,请记住,我们使用的大多数列表和seq都以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]]

结果,我认为最重要的不是您要公开的方法,例如,您可以::在List中使用,而我发现+:Seq 多余,我个人默认使用Seq。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.