序列特质 Seq、IndexedSeq 以及 LinearSeq
英文原文:http://docs.scala-lang.org/overviews/collections/seqs.html
Seq 特质表示的是序列。一个序列是一种具有下列特点的可迭代集合:它有一个length属性,而且它的每个元素都有固定的索引位置,索引从 0 开始。
后面表格中所总结的序列上的方法可以划分为下面几种类型:
- Indexing and Length 类操作,apply、isDefinedAt、length、indices 以及 lengthCompare。对于一个Seq的实例,apply 方法用于索引元素;因此一个类型为 Seq[T] 的序列是一个偏函数,它的参数(索引)为整数,返回一个类型 T 的序列元素。换而言之,Seq[T] 实现了 PartialFunction[Int, T] 特质。序列元素的索引从 0 开始一直到 序列的长度减一。序列上的 length 方法是一般集合上 size 方法的别名。lengthCompare 方法用于比较两个序列的长度,即使序列的大小是无限的。
- Index search 类操作,indexOf、lastIndexOf、indexOfSlice、lastIndexOfSlice、indexWhere、lastIndexWhere、segmentLength 以及 prefixLength,这些方法用于返回给定元素的索引或者满足一些谓词条件的元素的索引。
- Addition 类操作,+:、:+ 以及 padTo,用于在序列的头部或者尾部添加一些元素来生成一个新的序列。
- Update 类操作,updated 和 patch,用于更新原序列中一些元素之后得到的一个新的集合。
- Sorting 类操作,sorted、sortWith、sortBy,用于根据不同的原则对原序列进行排序。
- Reversal 类操作,reverse、reverseIterator 以及 reverseMap,用于逆序生成序列元素。
- Comparisons 类操作,startsWith、endsWith、contains、containsSlice 以及 correspods,用于将两个序列关联起来或者在原序列中查找一个指定元素。
- Multiset 类操作,intersect、diff、union 以及 distinct,用于对两个序列进行类似集合的操作,也包括去重。
如果一个序列是可变的,它还会提供一个带副作用的 update 方法,用于更新本身集合的元素。在 scala 中,像 seq(idx) = elem 这种语法只是函数调用 seq.update(idx) = elem 的缩写,因此 update 方法提供一个更方便的语法进行调用。注意 update 与 updated 方法的差异。update 方法更新本身集合的元素,并且只对可变的序列有效。 updated 方法对所有的序列都有效,并且总是返回一个新的集合而不是就地更改原来集合。
Seq 类中的方法
方法 | 作用 |
Indexing and Length: | |
xs(i) | (也可以写成 xs apply i)。索引 i 处的序列元素值 |
xs isDefinedAt i | 判断索引 i 是否包含在 xs.indices 中 |
xs.length | 序列的长度(与 size 相同意义) |
xs.lengthCompare ys | 如果 xs 长度小于 ys,则返回 -1; 如果 xs 长度大于 ys,则返回 +1 ; 如果两者长度相同,则返回 0。 这个方法在其中一个序列长度无限的情况下任然有效。 |
xs.indices | xs 的索引范围,从 0 到 xs.length - 1 |
Index Search: | |
xs indexOf x | 序列 xs 中等于 x 的第一个元素的索引值(存在几种变体) |
xs lastIndexOf x | 序列 xs 中等于 x 的最后一个元素的索引值(存在几种变体) |
xs indexOfSlice ys | 返回满足此条件的第一个索引值:从该索引开始的后续序列包含序列 ys |
xs lastIndexOfSlice | 返回满足此条件的最后一个索引值:从该索引开始的后续序列包含序列 ys |
xs indexWhere p | 序列 xs 中满足谓词条件 p 的第一个元素的索引值(存在几种变体) |
xs segmentLength (p, i) | 从 xs(i) 开始的满足谓词条件 p 的最长连续序列的长度 (即该序列中素有元素满足谓词条件 p) |
xs prefixLength p | 从第一个元素开始的满足谓词条件 p 的最长连续序列的长度 |
Additions: | |
x +: xs | 将 x 添加到 xs 前形成的一个新的序列 |
xs :+ x | 将 x 添加到 xs 后形成的一个新的序列 |
xs padTo (len, x) | 将 x 逐个添加到 xs 直到达到长度 len |
Updates: | |
xs patch (i, ys, r) | 将 xs 序列中从索引 i 开始的 r 个元素用序列 ys 替换 |
xs updated (i, x) | 返回将索引 i 处的元素替换为 x 的一个新的集合 |
xs(i) = x | (也可以这样写 xs.update(i, x),这个方法只对 mutable.Seq 可用) 将序列 xs 中索引 i 处的元素替换为 x |
Sorting: | |
xs.sorted | 返回对 xs 中元素按照该序列中元素类型的标准顺序进行排序的一个新的序列 |
xs sortWith lt | 返回对 xs 中元素按照 lt 比较操作进行排序的一个新的序列 |
xs sortBy f | 返回对 xs 中元素按照每个元素应用 f 函数的计算结果进行排序的一个新的序列 |
Reversals: | |
xs.reverse | 返回序列 xs 的一个逆序序列 |
xs.reverseIterator | 返回序列 xs 的一个逆序的迭代器 |
xs reverseMap f | 返回对序列 xs 逆序应用函数 f 得到的一个函数结果的序列 |
Comparisons: | |
xs startsWith ys | 判断序列 xs 是否以序列 ys 开头 |
xs endsWith ys | 判断序列 xs 是否以序列 ys 结尾 |
xs contains x | 判断序列 xs 是否包含元素 x |
xs containsSlice ys | 判断序列 xs 是否含有一个与序列 ys 值相同的序列 |
(xs corresponds ys) (p) | 判断序列 xs 中每一个元素与序列 ys 中对应索引的元素是否满足谓词条件 p |
Multiset Operations: | |
xs intersect ys | 序列 xs 中元素与序列 ys 中元素的交集,结果保留 xs 中元素的顺序 |
xs diff ys | 序列 xs 中元素与序列 ys 中元素的差集,结果保留 xs 中元素的顺序 |
xs union ys | 序列 xs 与序列 ys 的并集,同 xs ++ ys |
xs.dintinct | 返回序列 xs 中元素去重后的一个新的序列 |
Seq 特质有两个子特质 LinearSeq 和 IndexedSeq。他们并没有增加任何新的操作,只是为Seq中的一些方法提供了更高效的实现: LinearSeq (线性序列)提供了高效的 head 和 tail 方法,而 IndexedSeq(索引序列) 提供了高效的 apply、length 和 update 方法(当集合可变时)。常用的线性序列类的集合有 scala.collection.immutable.List 和 scala.collection.immutable.Stream。常用的索引序列类的集合有 scala.Array 以及 scala.collection.mutable.ArrayBuffer。Vector 类为索引访问与线性访问提供了一种折中的方案。它既达到常数时间的索引访问开销,又达到常数时间的线性访问开销。正因为如此,Vector 为既需要索引访问又需要线性访问的混合访问模式的场景奠定了一个良好的基础。有将会在后面学习到更多关于 vector 的知识。
Buffers
可变序列的一个重要的子类是 Buffer。这类集合不仅允许更新现有元素,而且还允许进行元素插入、删除以及高效的相会追加操作。Buffer 新加的主要方法有用于在序列尾部添加元素的 += 和 ++= 方法,用于在序列前端添加元素的 +=: 和 ++=:方法,用于插入元素的 insert 和 insertAll 方法,以及用于删除元素的 remove 和 -= 方法。这些方法在下面的表格中进行了总结。
两个常用的Buffer 实现是 ListBuffer 和 ArrayBuffer。如同其名字所表述的意思,ListBuffer 是由一个 List 支持,并且提供了高效转化成 List 的方法;而 ArrayBuffer 是由一个 Array 支持,并且提供了快速的转化成 Array 的方法。
Buffer 中的方法
方法 | 作用 |
Additions: | |
buf += x | 将给定元素 x 添加到 buffer 后面,并返回 buf 自己 |
buf += (x, y, z) | 讲所有给定元素添加到 buffer 后面,并返回 buf 自己 |
buf ++= xs | 将序列 xs 中所有元素添加到 buf 后面 |
buf +=: buf | 将元素 x 添加到 buf 的首部 |
xs ++=: buf | 将序列 xs 中所有元素添加到 buf 前面 |
buf insert (i, x) | 在 buf 的索引 i 位置处添加元素 x |
buf insertAll (i, xs) | 在 buf 的索引 i 位置处将序列 xs 中的所有元素依次添加 |
Removals: | |
buf -= x | 删除 buf 中第一个值为 x 的元素 |
buf remove i | 删除 buf 中索引 i 处的元素 |
buf remove (i, n) | 删除 buf 中从索引 i 开始的 n 个元素 |
buf trimStart n | 删除 buf 中开头 n 个元素 |
buf trimEnd n | 删除 buf 中最后 n 个元素 |
buf.clear | 删除 buf 中所有元素 |
Cloning: | |
buf.clone | 返回一个与 buf 具有相同元素的集合 |