8.1 常见的Scala容器
Scala主要的容器是List
、Set
和Map
。正如人们所预期的那样,List
是有序的对象容器,Set
是无序的容器,Map
是键值对的字典。Scala虽然也提供了可变的(mutable)容器,但它更倾向于使用不变的(immutable)版本。如果想修改容器而且对容器的所有操作都在一个线程里,可以选择可变容器。不过,如果计划跨线程或跨actor使用容器,不变容器会更好一些。不变容器不仅线程安全,而且没有副作用,有助于提升程序的正确性。在两个可供选择的包,只要在两个包选择一个即可:scala.collection.mutable
或scala.collection.immutable
。
UsingCollections/UsingSet.scala
val colors1 = Set("Blue", "Green", "Red")
var colors = colors1
println("colors1 (colors): " + colors)
colors += "Black"
println("colors: " + colors)
println("colors1: " + colors1)
上面的例子里,我们从一个具有三个颜色的Set
开始。然后,添加黑色,但这并不会修改原有的set
,而是得到了一个新的有四个元素的Set
,如下:
colors1 (colors): Set(Blue, Green, Red)
colors: Set(Blue, Green, Red, Black)
colors1: Set(Blue, Green, Red)
默认情况下,我们用的是不可变Set
。这是因为,默认包含的Predef
对象为Set
和Map
提供的别名指向的是不变实现。Set
和Map
都是collection
包里的trait,其对应的可变版本在scala.collection.mutable
里,而不变版本在scala.collection.immutable
里。
上面的例子里,创建Set
的实例没有用new
,所以,没有写成下面这样:
val colors1 = new scala.collection.immutable.Set3[String]
("Blue", "Green", "Red")
而是用了更为简洁的val colors1 = Set("Blue", "Green", "Red")
①。Scala会知道我们需要的是哪个Set[String]
。类似的,如果写成Set(1, 2, 3)
,得到就是个Set[Int]
。特殊的apply()
方法——也称为工厂方法——让这一切成为可能。类似于X(…)
的语句,其中X
是个类名或实例引用,会当作X.apply(…)
处理。这样,如果类的伴生对象有apply()
方法的话,Scala会自动调用,而Map
和List
是有apply()
方法的。
①
Set3
是一个类,表示包含有3个元素的set
实现。