8.1 常见的Scala容器

Scala主要的容器是ListSetMap。正如人们所预期的那样,List是有序的对象容器,Set是无序的容器,Map是键值对的字典。Scala虽然也提供了可变的(mutable)容器,但它更倾向于使用不变的(immutable)版本。如果想修改容器而且对容器的所有操作都在一个线程里,可以选择可变容器。不过,如果计划跨线程或跨actor使用容器,不变容器会更好一些。不变容器不仅线程安全,而且没有副作用,有助于提升程序的正确性。在两个可供选择的包,只要在两个包选择一个即可:scala.collection.mutablescala.collection.immutable

UsingCollections/UsingSet.scala

  1. val colors1 = Set("Blue", "Green", "Red")
  2. var colors = colors1
  3. println("colors1 (colors): " + colors)
  4. colors += "Black"
  5. println("colors: " + colors)
  6. println("colors1: " + colors1)

上面的例子里,我们从一个具有三个颜色的Set开始。然后,添加黑色,但这并不会修改原有的set,而是得到了一个新的有四个元素的Set,如下:

  1. colors1 (colors): Set(Blue, Green, Red)
  2. colors: Set(Blue, Green, Red, Black)
  3. colors1: Set(Blue, Green, Red)

默认情况下,我们用的是不可变Set。这是因为,默认包含的Predef对象为SetMap提供的别名指向的是不变实现。SetMap都是collection包里的trait,其对应的可变版本在scala.collection.mutable里,而不变版本在scala.collection.immutable里。

上面的例子里,创建Set的实例没有用new,所以,没有写成下面这样:

  1. val colors1 = new scala.collection.immutable.Set3[String]
  2. ("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会自动调用,而MapList是有apply()方法的。

Set3是一个类,表示包含有3个元素的set实现。