我在许多示例中看到,有时使用 Seq,而其他时候使用 List ...
除了前者是 Scala 类型和 List 来自 Java 之外,有什么区别吗?
在 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.Seq
、collection.mutable.Seq
和 collection.immutable.Seq
,而后者是导入范围的“默认”。
还有 GenSeq
和 ParSeq
。后一种方法在可能的情况下并行运行,而前一种方法是 Seq
和 ParSeq
的父类,当代码的并行性无关紧要时,这是一个合适的概括。它们都是相对较新引入的,因此人们还没有太多使用它们。
Seq 是具有已定义元素顺序的 Iterable。序列提供了一种方法 apply()
用于索引,范围从 0 到序列的长度。 Seq 有许多子类,包括 Queue、Range、List、Stack 和 LinkedList。
List 是作为不可变链表实现的 Seq。它最适用于具有后进先出 (LIFO) 访问模式的情况。
以下是 Scala FAQ 中的完整集合类层次结构:
https://i.stack.imgur.com/2fjoA.png
prepend()
和 head()
操作作为 O(1) vs append()
OR last()
,这是列表中元素数量的 O(n)。
Seq
是 List
实现的特征。
如果您将容器定义为 Seq
,则可以使用任何实现 Seq
特征的容器。
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
。
在 Scala 中,List 继承自 Seq,但实现了 Product;这是 List 的正确定义:
sealed abstract class List[+A] extends AbstractSeq[A] with Product with ...
[注意:the actual definition 稍微复杂一点,以适应和利用 Scala 非常强大的集合框架。]
正如@daniel-c-sobral 所说,List 扩展了 trait 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默认。
String
不是集合,但它是 Java 程序员熟悉的不可变类的示例。UnsupportedOperationException
。要在 Java 中创建不可变列表,您可以使用 Collections.unmodifiableList(),同样还有其他方法用于 Set、Map 等。docs.oracle.com/javase/6/docs/api/java/util/…