集合(Scala 2.8 - 2.12)

序列特征 Seq、IndexedSeq 和 LinearSeq

语言

Seq 特征表示序列。序列是一种可迭代的对象,它具有 length,并且其元素具有从 0 开始的固定索引位置。

序列上的操作(下表中总结)属于以下类别

  • 索引和长度操作 applyisDefinedAtlengthindiceslengthCompare。对于 Seqapply 操作表示索引;因此,类型为 Seq[T] 的序列是一个部分函数,它接受一个 Int 参数(索引),并生成一个类型为 T 的序列元素。换句话说,Seq[T] 扩展了 PartialFunction[Int, T]。序列的元素从零开始索引,直到序列的 length 减一。序列上的 length 方法是通用集合的 size 方法的别名。lengthCompare 方法允许您将序列的长度与一个 Int 进行比较,即使序列具有无限长度。
  • 索引搜索操作 indexOflastIndexOfindexOfSlicelastIndexOfSliceindexWherelastIndexWheresegmentLengthprefixLength,它们返回一个等于给定值或匹配某个谓词的元素的索引。
  • 添加操作 +::+padTo,它们返回通过在序列的开头或结尾添加元素而获得的新序列。
  • 更新操作 updatedpatch,它们返回通过替换原始序列中某些元素而获得的新序列。
  • 排序操作 sortedsortWithsortBy,这些操作根据各种条件对序列元素进行排序。
  • 反转操作 reversereverseIteratorreverseMap,这些操作以相反的顺序产生或处理序列元素。
  • 比较 startsWithendsWithcontainscontainsSlicecorresponds,这些操作将两个序列关联起来或在序列中搜索元素。
  • 多重集 操作 intersectdiffuniondistinct,这些操作对两个序列的元素执行类似集合的操作或删除重复项。

如果序列是可变的,它还提供一个产生副作用的 update 方法,该方法允许更新序列元素。与 Scala 中一贯的做法一样,seq(idx) = elem 这样的语法只是 seq.update(idx, elem) 的简写,因此 update 免费提供了方便的赋值语法。请注意 updateupdated 之间的区别。update 就地更改序列元素,并且仅适用于可变序列。updated 适用于所有序列,并且始终返回一个新序列,而不是修改原始序列。

Seq 类中的操作

是什么 做什么
索引和长度  
xs(i) (或者写成 xs apply i)。索引为 ixs 元素。
xs isDefinedAt i 测试 i 是否包含在 xs.indices 中。
xs.length 序列的长度(与 size 相同)。
xs lengthCompare n 如果 xs 短于 n,则返回 -1,如果更长,则返回 +1,如果长度为 n,则返回 0。即使序列是无限的,此方法也能正常工作,例如 Stream.from(1) lengthCompare 42 等于 +1
xs.indices 0 延伸到 xs.length - 1xs 的索引范围。
索引搜索  
xs indexOf x xs 中等于 x 的第一个元素的索引(有几种变体)。
xs lastIndexOf x xs 中等于 x 的最后一个元素的索引(有几种变体)。
xs indexOfSlice ys xs 的第一个索引,从该索引开始的连续元素形成序列 ys。
xs lastIndexOfSlice ys xs 的最后一个索引,从该索引开始的连续元素形成序列 ys。
xs indexWhere p xs 中满足 p 的第一个元素的索引(有几种变体)。
xs segmentLength (p, i) xs 中元素的最长不间断段的长度,从 xs(i) 开始,所有元素都满足谓词 p。
xs prefixLength p xs 中元素的最长前缀的长度,所有元素都满足谓词 p。
添加  
x +: xs 一个新序列,由 x 前置于 xs 组成。
xs :+ x 一个新序列,由 x 附加到 xs 组成。
xs padTo (len, x) 将值 x 附加到 xs,直到达到长度 len,由此产生的序列。
更新  
xs patch (i, ys, r) 从 i 开始用修补程序 ys 替换 xs 的 r 个元素,由此产生的序列。
xs updated (i, x) xs 的副本,其中索引 i 处的元素被 x 替换。
xs(i) = x (或者写成 xs.update(i, x),仅适用于 mutable.Seq)。将 xs 中索引 i 处的元素更改为 x。
排序  
xs.sorted 使用 xs 元素类型的标准排序对 xs 的元素进行排序后获得的新序列。
xs sortWith lt 使用 lt 作为比较操作对 xs 的元素进行排序后获得的新序列。
xs sortBy f xs 的元素进行排序后获得的新序列。对两个元素之间的比较通过对这两个元素映射函数 f 并比较结果来进行。
反转  
xs.reverse 一个序列,其中包含 xs 的元素,顺序相反。
xs.reverseIterator 一个迭代器,生成 xs 的所有元素,顺序相反。
xs reverseMap f 一个序列,通过对 xs 的元素按相反顺序映射 f 获得。
比较  
xs startsWith ys 测试 xs 是否以序列 ys 开头(有多种变体)。
xs endsWith ys 测试 xs 是否以序列 ys 结尾(有多种变体)。
xs contains x 测试 xs 是否有等于 x 的元素。
xs containsSlice ys 测试 xs 是否有等于 ys 的连续子序列。
(xs corresponds ys)(p) 测试 xsys 的相应元素是否满足二元谓词 p
多重集操作  
xs intersect ys 序列 xsys 的多重集交集,保留 xs 中元素的顺序。
xs diff ys 序列 xsys 的多重集差集,保留 xs 中元素的顺序。
xs union ys 多重集并集;与 xs ++ ys 相同。
xs.distinct 不包含重复元素的 xs 子序列。

Trait Seq 有两个子 trait LinearSeqIndexedSeq。它们不会添加任何新操作,但各自提供不同的性能特征:线性序列具有高效的 headtail 操作,而索引序列具有高效的 applylength 和(如果可变)update 操作。常用的线性序列是 scala.collection.immutable.Listscala.collection.immutable.Stream。常用的索引序列是 scala.Arrayscala.collection.mutable.ArrayBufferVector 类在索引访问和线性访问之间提供了一个有趣的折衷方案。它既具有恒定时间的索引开销,又具有恒定时间的线性访问开销。因此,向量是同时使用索引访问和线性访问的混合访问模式的良好基础。您将在 后面 了解更多有关向量的知识。

缓冲区

可变序列的一个重要子类别是 Buffer。它们不仅允许更新现有元素,还允许插入元素、移除元素以及在缓冲区末尾高效添加新元素。缓冲区支持的主要新方法是 +=++=(用于在末尾添加元素)、+=:++=:(用于在开头添加元素)、insertinsertAll(用于插入元素)以及 remove-=(用于移除元素)。下表总结了这些操作。

两个经常使用的缓冲区实现是 ListBufferArrayBuffer。顾名思义,ListBufferList 支持,并支持将其元素有效地转换为 List,而 ArrayBuffer 由数组支持,并且可以快速转换为数组。

Buffer 类中的操作

是什么 做什么
添加  
buf += x 将元素 x 追加到缓冲区,并将 buf 本身作为结果返回。
buf += (x, y, z) 将给定的元素追加到缓冲区。
buf ++= xs xs 中的所有元素追加到缓冲区。
x +=: buf 将元素 x 前置到缓冲区。
xs ++=: buf xs 中的所有元素前置到缓冲区。
buf insert (i, x) 在缓冲区的索引 i 处插入元素 x
buf insertAll (i, xs) 在缓冲区的索引 i 处插入 xs 中的所有元素。
删除  
buf -= x 从缓冲区中删除元素 x
buf remove i 从缓冲区中删除索引 i 处的元素。
buf remove (i, n) 从缓冲区中删除从索引 i 开始的 n 个元素。
buf trimStart n 从缓冲区中删除前 n 个元素。
buf trimEnd n 从缓冲区中删除后 n 个元素。
buf.clear() 从缓冲区中删除所有元素。
克隆  
buf.clone 一个与 buf 具有相同元素的新缓冲区。

此页面的贡献者