我在很多例子中看到有时使用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
的父级,对于代码的并行性无关紧要时是一种合适的推广。它们都是相对较新引入的,所以人们还没有使用它们。
在Scala中,List继承自Seq,但实现了Product;这是List的正确定义:
sealed abstract class List[+A] extends AbstractSeq[A] with Product with ...
[注意:the actual definition有点复杂,为了适应和利用Scala非常强大的集合框架。
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
。