Scala中Seq和List的区别
我在许多例子中看到,有时使用Seq,而其他时间则使用ListScala中Seq和List的区别,list,scala,collections,seq,List,Scala,Collections,Seq,我在许多例子中看到,有时使用Seq,而其他时间则使用List 除了前者是Scala类型和来自Java的列表之外,还有什么区别吗?在Scala中,列表继承自Seq,但实现了;以下是正确的定义: [注意:为了适应和利用Scala非常强大的收集框架,有点复杂。]用Java术语来说,Scala的Seq将是Java的列表,Scala的列表将是Java的链接列表 请注意,Seq是一种trait,它相当于Java的接口,但相当于新兴的defender方法。Scala的List是一个抽象类,由Nil和:扩展,这
除了前者是Scala类型和来自Java的列表之外,还有什么区别吗?在Scala中,列表继承自Seq,但实现了;以下是正确的定义:
[注意:为了适应和利用Scala非常强大的收集框架,有点复杂。]用Java术语来说,Scala的
Seq
将是Java的列表
,Scala的列表
将是Java的链接列表
请注意,Seq
是一种trait
,它相当于Java的接口
,但相当于新兴的defender方法。Scala的List
是一个抽象类,由Nil
和:
扩展,这是List
的具体实现
因此,Java的列表
是一个接口
,Scala的列表
是一个实现
除此之外,Scala的列表
是不可变的,这与LinkedList
不同。事实上,Java没有与不可变集合等价的东西(只读的东西可以保证新对象不能被更改,但您仍然可以更改旧对象,因此也可以更改“只读”对象)
Scala的列表
经过编译器和库的高度优化,是函数式编程中的基本数据类型。然而,它有局限性,不适合并行编程。如今,Vector
比List
更好,但习惯很难打破
Seq
是序列的一个很好的泛化,所以如果你编程到接口,你应该使用它。请注意,它们实际上有三个:collection.Seq
、collection.mutable.Seq
和collection.immutable.Seq
,后者是导入范围的“默认值”
还有GenSeq
和ParSeq
。后一种方法在可能的情况下并行运行,而前一种方法是Seq
和ParSeq
的父方法,对于代码的并行性无关紧要的情况,这是一种合适的泛化。它们都是相对较新引入的,因此人们还没有太多地使用它们。A是一个具有定义的元素顺序的Iterable。序列为索引提供了一种方法apply()
,范围从0到序列长度。Seq有许多子类,包括Queue、Range、List、Stack和LinkedList
A是作为不可变链表实现的Seq。它最好用于后进先出(LIFO)访问模式的情况
以下是来自的完整集合类层次结构:
Seq
是列表
实现的一种特性
如果将容器定义为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
,正如@daniel-c-sobral所说,List扩展了trait 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]]
因此,我认为唯一重要的是您想要公开的方法,例如,为了预先结束您可以使用列表中的
:
,我发现它与Seq中的+:
多余,我个人默认使用Seq RE“Java没有等价于不可变集合”,虽然String
不是集合,但它是Java程序员熟悉的不可变类的一个例子。@huynhjl,这与问题无关。我把Java中存在的东西和Scala中存在的东西进行了比较,Java中没有任何可变/不可变集合的概念,Java实际上具有不可变集合的等价物。这并不是“宣传得很好”,但它确实存在,而且当你大量使用泛型时,你很可能会因此遇到一些不支持的操作异常。要在Java中创建一个不可变列表,可以使用Collections.unmodifiableList()和其他类似的集合、映射等方法@jbx Not true。如果您使用这些方法,您将得到一个对象,它将在修改它的方法上抛出异常,但不是一个不可变的对象。如果原始对象在不可修改对象创建后被修改,则不可修改对象将反映该情况。因此,不可修改,是的,不可变,否。@jbx接收方法不能保留对它接收的集合的引用,并假设它永远不会更改,并且标准Java库中没有任何类型可以保证这一点——这就是不可变性。因此,例如,该接收方法不能保证线程安全。这甚至没有触及不变性所带来的持久性特征。如果没有所有这些,它就不能被称为“等效”。数组(和ArrayBuffer)在哪里?这是不可忍受的
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]]