In [2]:
val seq1 = Seq("Programming", "Scala")
val seq2 = "People" +: "should" +: "read" +: Seq.empty
val seq3 = seq2 ++ seq1
可以考虑用immutable.Vector代替List,因为不可变Vector的所有操作都是O(1),而List对于那些需要访问头部以外元素的操作,都需要O(n)操作。
有关预定义的讨论
为了鼓励程序员使用不可变的集合类型,Predef在暴露不可变集合类型时,不需要显示导入或使用全路径导入。但是Predef还将scala.collection.Seq导入到了当前作用域,该类型是可变集合类型和不可变集合类型共同的抽象特质,这使得传入的Seq类型实例可能是可变的,所以线程是不安全的。
为了使用scala.collection.immutable.Seq代替默认的scala.collection.Seq,使用包对象来解决:
package fp
package object datastructs {
type Seq[+A] = scala.collection.immutable.Seq[A]
val Seq = scala.collection.immutable.Seq
}
package关键字也是包对象定义的一部分,在一个包中只能有一个包对象。最后,该文件的路径是src/main/scala/fp/datastructs/package.scala,这是一种常用的命名习惯。
在包对象中,我们声明了一个类型别名和一个val变量。类型声明导入之后,使用Seq声明一个实例时,就需要使用scala.collection.immutable.Seq;val Seq的声明语句将伴随对象引入作用域,于是类似Seq(1,2,3,4)的语句就会触发scala.collection.immutable.Seq.apply方法的调用。
In [3]:
val stateCapitals = Map(
"Alabama" -> "Montgomery",
"Alaska" -> "Juneau",
"Wyoming" -> "Cheyenne"
)
In [4]:
val lengths = stateCapitals map {
kv => (kv._1, kv._2.length)
}
In [5]:
val caps = stateCapitals map {
case (k, v) => (k, v.toUpperCase)
}
In [6]:
val stateCapitals2 = stateCapitals + ("Virginia" -> "Richmond")
key -> value的语法形式实际上用库中的隐式转换实现的,实际调用了Map.apply方法。Map.apply方法的参数为一个两元素的元组(键值对)。
In [7]:
val states = Set("Alabama", "Alaska", "Wyoming")
In [8]:
val lengths = states map (st => st.length)
In [9]:
val states2 = states + ("New York", "Illinois")