我在很多例子中看到有时使用Seq,而有时则使用List...
除了前者是Scala类型而List来自Java之外,它们是否有任何区别?
我在很多例子中看到有时使用Seq,而有时则使用List...
除了前者是Scala类型而List来自Java之外,它们是否有任何区别?
Seq
相当于Java的List
,Scala的List
相当于Java的LinkedList
。Seq
是一个trait,类似于Java的interface,但具有即将推出的defender方法的等效。Scala的List
是一个抽象类,由Nil
和::
扩展,它们是List
的具体实现。List
是一个接口,而在Scala中,List
是一个实现。List
是不可变的,而LinkedList
则不是。事实上,Java没有不可变集合的等价物(只读保证新对象不能被更改,但您仍然可以更改旧对象,因此“只读”也会被更改)。List
经过编译器和库高度优化,是函数式编程中的基本数据类型。然而,它存在一些限制,对于并行编程来说是不足的。这些天,Vector
比List
更好,但习惯难以改变。Seq
是序列的很好的概括,因此如果您按照接口进行编程,应该使用它。需要注意的是,实际上有三个:collection.Seq
,collection.mutable.Seq
和collection.immutable.Seq
,后者是默认导入到作用域中的。GenSeq
和ParSeq
。后者在可能的情况下并行运行,而前者是Seq
和ParSeq
的父类,适用于没有对代码并行性的担忧时进行概括。它们都比较新,所以人们使用它们的次数不多。prepend()
和head()
操作,其时间复杂度为O(1),而不是append()
或last()
操作,后者的时间复杂度为列表中元素的数量O(n)。 - RicardoSeq
是 List
实现的一个 trait。
如果你将你的容器定义为 Seq
,你可以使用任何实现了 Seq
trait 的容器。
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
。
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。"最初的回答"
String
不是一个集合,但它是Java程序员熟悉的不可变类的例子。 - huynhjlUnsupportedOperationException
。在Java中创建不可变列表,您可以使用Collections.unmodifiableList(),类似地,还有其他方法用于Sets、Maps等。http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#unmodifiableList(java.util.List) - jbx