问题:
你需要为你的Scala应用选择一个快速,通用的不可变序列集合类型,那么该如何选择呢?
解决:
Vecotr类目前可以被认为是这么一个通用的不可变数据结构。Vector是一个带索引的不可变序列容器,如果你更倾向于使用一个链式不可变集合容器,那么你可以选择List。
创建和使用一个Vector,就像其它的不可变带索引的序列容器一样。你可以创建和高效地通过索引来访问集合中的元素。
scala> val v = Vector("a", "b", "c")
v: scala.collection.immutable.Vector[String] = Vector(a, b, c)
scala> v(1)
res2: String = b
你不能改变一个Vector,但是你可以给Vector添加一个元素,产生一个新的Vector然后用一个新的变量来指向这个Vector
scala> val a = Vector(1, 2, 3)
a: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> val b = a ++ Vector(4, 5)
b: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)
你可以使用update方法替换Vector中的元素,生成一个新的Vector然后用一个新的变量来指向这个新的Vector
scala> val a = Vector(1, 2, 3)
a: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> val b = a.updated(0, 4)
b: scala.collection.immutable.Vector[Int] = Vector(4, 2, 3)
你同样可以使用容器通用方法来获取你想要的元素,比如task,filter
scala> val a = Vector(1, 2, 3)
a: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> val b = a.take(2)
b: scala.collection.immutable.Vector[Int] = Vector(1, 2)
scala> val c = a.filter(_ >= 2)
c: scala.collection.immutable.Vector[Int] = Vector(2, 3)
就像上一节说的一样,你同样可以使用一个可变变量指向一个不可变容器,然后改变容器内容返回一个新的容器
scala> val a = Vector(1, 2, 3)
a: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> val b = a ++ Vector(4,5)
b: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)
讨论:
Vector作为一个集合类型,按地址随机存取元素效率是比较低的。但是Vector访问列表元素是高效的,可以在常量时间诶完成。Vector在快速随机访问和快速随机存取方面是比较均衡的,Vectors现在是immutable indexed sequences的默认实现。当你不知掉该选择什么时,Vector是你对好的选择,因为它在Scala集合中是最灵活和高效的。
如果你创建一个IndexedSeq的实例,Scala就会给你一个Vector:
scala> val x = IndexedSeq(1,2,3)
x: IndexedSeq[Int] = Vector(1, 2, 3)
最后,许多可发人员更新换直接创建一个IndexedSeq在他们的代码中,而不是使用Vector,因为这样会让他们的代码更能适应未来Scala的变化。