首页 > 代码库 > scala编程第17章学习笔记(3)

scala编程第17章学习笔记(3)

可变(mutable)集合与不可变(immutable)集合

为了更易于完成不可变集合到可变集合的转换,或者反向转换,Scala提供了一些语法糖。纵使不可变集和映射并不支持真正的+=方法,Scala还是为此提供了+=的语法解释。

scala> val people = Set("Nancy", "Jane")people: scala.collection.immutable.Set[String] = Set(Nancy, Jane)scala> people += "Bob"<console>:9: error: value += is not a member of scala.collection.immutable.Set[String]              people += "Bob"                     ^

然而如果people声明为var,而不是val,那么集合就可以用+=操作完成“更新”,尽管它是不可变类型的。首先,新创建集合;然后,people将被重新赋值为新集合:

scala> var people = Set("Nancy", "Jane")people: scala.collection.immutable.Set[String] = Set(Nancy, Jane)scala> people += "Bob"scala> peopleres2: scala.collection.immutable.Set[String] = Set(Nancy, Jane, Bob)

同样的理念可以应用于所有以=结尾的方法,而不仅是+=方法。以下代码把该语法应用于-=操作符,从集中移除元素;以及++=操作符,把集合的所有元素添加到集里面:

scala> people -= "Jane"scala> people ++= List("Tom", "Harry")scala> peopleres5: scala.collection.immutable.Set[String] = Set(Nancy, Bob, Tom, Harry)

这块语法糖不仅对集合有效,它还具有普适性。例如,下面是用在浮点数上的:

scala> var roughlyPi = 3.0roughlyPi: Double = 3.0scala> roughlyPi += 0.1scala> roughlyPi += 0.04scala> roughlyPires8: Double = 3.14

这种扩展的效果类似于Java的赋值操作符+=、-=、*=等,不过其更为通用,因为所有以=结尾的操作符都可以做转化。

初始化集合

最常见的创建和初始化集合的方法是把初始值传递给要用的集合类型的伴生对象的工厂方法。你只须把元素放在伴生对象名后面的括号中,Scala编译器就会把它转化为该伴生对象的apply方法调用:

scala> List(1, 2, 3)res9: List[Int] = List(1, 2, 3)scala> Set(‘a‘, ‘b‘, ‘c‘)res10: scala.collection.immutable.Set[Char] = Set(a, b, c)scala> import scala.collection.mutableimport scala.collection.mutablescala> mutable.Map("hi" -> 2, "there" -> 5)res11: scala.collection.mutable.Map[String,Int] = Map(hi -> 2, there -> 5)scala> Array(1.0, 2.0, 3.0)res12: Array[Double] = Array(1.0, 2.0, 3.0)

尽管通常都可以让Scala的编译器从传递给工厂方法的元素推断集合的元素类型,但有些时候或许你会希望指定以不同于编译器所选的类型创建集合。尤其对于可变集合来说更是如此。举例如下:

scala> import scala.collection.mutableimport scala.collection.mutablescala> val stuff = mutable.Set(42)stuff: scala.collection.mutable.Set[Int] = Set(42)scala> stuff += "abracadabra"<console>:11: error: type mismatch; found   : String("abracadabra") required: Int              stuff += "abracadabra"                       ^

这里的问题在于stuff被指定的类型为Int。如果想要让它的类型为Any,你需要明确地说明,把元素类型放在方括号里,如下:

scala> val stuff = mutable.Set[Any](42)stuff: scala.collection.mutable.Set[Any] = Set(42)scala> stuff += "abracadabra"res14: stuff.type = Set(abracadabra, 42)

另一种特殊情况是,你想要把集合初始化为指定类型。例如,设想你要把列表中的元素保存在TreeSet中。列表如下:

scala> val colors = List("blue", "yellow", "red", "green")colors: List[String] = List(blue, yellow, red, green)

你不能把colors列表传递给TreeSet工厂方法:

scala> import scala.collection.immutable.TreeSetimport scala.collection.immutable.TreeSetscala> val treeSet = TreeSet(colors)<console>:11: error: No implicit Ordering defined for List[String].       val treeSet = TreeSet(colors)                            ^

实际上,需要创建空的TreeSet[String]对象并使用TreeSet的++操作符把列表元素加入其中:

scala> val treeSet = TreeSet[String]() ++ colorstreeSet: scala.collection.immutable.TreeSet[String] = TreeSet(blue, green, red,yellow)

 

scala编程第17章学习笔记(3)