集合

序列特征 Seq、IndexedSeq 和 LinearSeq

语言

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

序列上的操作(总结在下表中)分为以下几类

  • 索引和长度操作 applyisDefinedAtlengthindiceslengthCompare。对于 Seqapply 操作表示索引;因此,类型为 Seq[T] 的序列是一个偏函数,它采用 Int 参数(一个索引),并生成类型为 T 的序列元素。换句话说,Seq[T] 扩展了 PartialFunction[Int, T]。序列的元素从零开始索引,直到序列的 length 减一。序列上的 length 方法是一般集合的 size 方法的别名。lengthCompare 方法允许您将序列的长度与 Int 或 Iterable 进行比较,即使序列具有无限长度。
  • 索引搜索操作 indexOflastIndexOfindexOfSlicelastIndexOfSliceindexWherelastIndexWheresegmentLength,它们返回等于给定值或匹配某个谓词的元素的索引。
  • 加法操作 prependedprependedAllappendedappendedAllpadTo,它们返回通过在序列的前面或末尾添加元素而获得的新序列。
  • 更新操作 updatedpatch,它们返回通过替换原始序列中的一些元素而获得的新序列。
  • 排序操作 sortedsortWithsortBy,它们根据各种标准对序列元素进行排序。
  • 反转操作 reversereverseIterator,它们生成或处理反向顺序的序列元素。
  • 比较 startsWithendsWithcontainscontainsSlicecorrespondssearch,它们关联两个序列或在序列中搜索元素。
  • 多重集 操作 intersectdiffdistinctdistinctBy,它们对两个序列的元素执行类似集合的操作或移除重复项。

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

Seq 类中的操作

它是什么 它做什么
索引和长度  
xs(i) (或写成 xs.apply(i))。xs 在索引 i 处的元素。
xs.isDefinedAt(i) 测试 i 是否包含在 xs.indices 中。
xs.length 序列的长度(与 size 相同)。
xs.lengthCompare(n) 如果 xs 短于 n,则返回 -1,如果它更长,则返回 +1,如果它的长度为 n,则返回 0。即使序列是无限的,此方法也能正常工作,例如 LazyList.from(1).lengthCompare(42) 返回一个正值。
xs.indices 索引范围 xs,从 0 扩展到 xs.length - 1
索引搜索  
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.prepended(x)
x +: xs
一个新的序列,其中包含 x 前置于 xs
xs.prependedAll(ys)
ys ++: xs
一个新的序列,其中包含 ys 的所有元素前置于 xs
xs.appended(x)
xs :+ x
一个新的序列,其中包含 x 附加于 xs
xs.appendedAll(ys)
xs :++ ys
一个新序列,由所有元素 ys 附加到 xs 组成。
xs.padTo(len, x) 通过将值 x 附加到 xs,直到达到长度 len,得到的结果序列。
更新  
xs.patch(i, ys, r) 通过用修补程序 ys 替换从 i 开始的 xsr 个元素,得到的结果序列。
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.sameElements(ys) 一个测试,用于判断 xsys 是否包含相同的元素,顺序也相同
xs.startsWith(ys) 测试 xs 是否以序列 ys 开头(有多种变体)。
xs.endsWith(ys) 测试 xs 是否以序列 ys 结尾(有几种变体)。
xs.contains(x) 测试 xs 是否具有等于 x 的元素。
xs.search(x) 测试已排序序列 xs 是否具有等于 x 的元素,可能比 xs.contains(x) 更有效率。
xs.containsSlice(ys) 测试 xs 是否具有等于 ys 的连续子序列。
xs.corresponds(ys)(p) 测试 xsys 的对应元素是否满足二元谓词 p
多重集操作  
xs.intersect(ys) 序列 xsys 的多重集交集,保留 xs 中元素的顺序。
xs.diff(ys) 序列 xsys 的多重集差集,保留 xs 中元素的顺序。
xs.distinct 不包含重复元素的 xs 子序列。
xs.distinctBy(f) 在应用转换函数 f 后不包含重复元素的 xs 子序列。例如,List("foo", "bar", "quux").distinctBy(_.length) == List("foo", "quux")

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

在可变分支上,IndexedSeq 添加了用于就地转换其元素的操作(与 mapsort 等转换操作相反,这些操作在根 Seq 上可用,并返回一个新集合实例)。

可变的 IndexedSeq 类中的操作

它是什么 它做什么
转换  
xs.mapInPlace(f) 通过将 f 函数应用于 xs 的每个元素,转换 xs 的所有元素。
xs.sortInPlace() 对集合 xs 进行排序。
xs.sortInPlaceWith(c) 根据给定的比较函数 c 对集合 xs 进行排序。
xs.sortInPlaceBy(f) 根据对函数 f 应用于每个元素的结果定义的顺序,对集合 xs 进行排序。

缓冲区

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

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

Buffer 类中的操作

它是什么 它做什么
添加  
buf.append(x)
buf += x
将元素 x 追加到缓冲区,并返回 buf 本身作为结果。
buf.appendAll(xs)
buf ++= xs
xs 中的所有元素追加到缓冲区。
buf.prepend(x)
x +=: buf
将元素 x 预置到缓冲区。
buf.prependAll(xs)
xs ++=: buf
xs 中的所有元素预置到缓冲区。
buf.insert(i, x) 在缓冲区的索引 i 处插入元素 x
buf.insertAll(i, xs) 在缓冲区的索引 i 处插入 xs 中的所有元素。
buf.padToInPlace(n, x) 将元素 x 追加到缓冲区,直到缓冲区中共有 n 个元素。
删除  
buf.subtractOne(x)
buf -= x
从缓冲区中删除元素 x
buf.subtractAll(xs)
buf --= xs
从缓冲区中删除 xs 中的元素。
buf.remove(i) 从缓冲区中删除索引 i 处的元素。
buf.remove(i, n) 从缓冲区中删除从索引 i 开始的 n 个元素。
buf.trimStart(n) 从缓冲区中删除前 n 个元素。
buf.trimEnd(n) 从缓冲区中删除后 n 个元素。
buf.clear() 从缓冲区中删除所有元素。
替换  
buf.patchInPlace(i, xs, n) xs 中的元素替换缓冲区的(最多)n 个元素,从缓冲区中的索引 i 开始。
克隆  
buf.clone() 一个与 buf 具有相同元素的新缓冲区。

此页面的贡献者