集合

特质 Iterable

语言

在集合层次结构的顶部是特质 Iterable。此特质中的所有方法均根据抽象方法 iterator 定义,该方法逐个生成集合的元素。

def iterator: Iterator[A]

实现 Iterable 的集合类只需定义此方法;所有其他方法都可以从 Iterable 继承。

Iterable 还定义了许多具体方法,所有这些方法都列在以下表格中。这些方法属于以下类别

  • 添加concat,它将两个集合连接在一起,或将迭代器的所有元素追加到集合中。
  • 映射操作 mapflatMapcollect,它们通过对集合元素应用某些函数来生成新集合。
  • 转换 totoListtoVectortoMaptoSettoSeqtoIndexedSeqtoBuffertoArray,它们将 Iterable 集合转换为更具体的内容。如果目标是可变集合(to(collection.mutable.X)toArraytoBuffer),则通过复制原始元素来创建新集合。如果集合的运行时类型已与所需集合类型匹配,则所有这些转换都会返回其接收器参数不变。例如,对列表应用 toList 将生成列表本身。
  • 复制操作 copyToArray。顾名思义,这会将集合元素复制到数组中。
  • 大小信息操作 isEmptynonEmptysizeknownSizesizeIs。在某些情况下,集合的元素数量可能需要遍历(例如,List)。在其他情况下,集合可以有无限数量的元素(例如,LazyList.from(1))。
  • 元素检索操作 headlastheadOptionlastOptionfind。这些操作选择集合的第一个或最后一个元素,或者选择第一个与条件匹配的元素。但是,请注意,并非所有集合都对“第一个”和“最后一个”的含义有明确的定义。例如,哈希集可能会根据其哈希键存储元素,而哈希键可能会在每次运行时发生变化。在这种情况下,哈希集的“第一个”元素对于程序的每次运行也可能不同。如果集合始终以相同的顺序生成其元素,则该集合为有序集合。大多数集合是有序的,但有些集合(例如哈希集)不是有序的——放弃排序会带来一些额外的效率。排序通常对于提供可重复的测试和帮助调试至关重要。这就是 Scala 集合为所有集合类型提供有序备选方案的原因。例如,HashSet 的有序备选方案是 LinkedHashSet
  • 子集合检索操作 tailinitslicetakedroptakeWhiledropWhilefilterfilterNotwithFilter。这些操作都返回由索引范围或某个谓词标识的某个子集合。
  • 细分操作 splitAtspanpartitionpartitionMapgroupBygroupMapgroupMapReduce,这些操作将此集合的元素拆分为多个子集合。
  • 元素测试 existsforallcount,这些操作使用给定的谓词测试集合元素。
  • 折叠 foldLeftfoldRightreduceLeftreduceRight,这些折叠对连续的元素应用二元操作。
  • 特定折叠 sumproductminmax,这些折叠适用于特定类型(数字或可比较类型)的集合。
  • 字符串 操作 mkStringaddString 提供了将集合转换为字符串的替代方法。
  • 视图 操作:视图是一个延迟求值的集合。您将在 稍后 了解有关视图的更多信息。

Iterable 中还存在另外两种返回迭代器的函数:groupedsliding。但是,这些迭代器不会返回单个元素,而是返回原始集合中元素的整个子序列。这些子序列的最大大小作为参数提供给这些函数。grouped 函数以“分块”增量返回其元素,而 sliding 在元素上生成一个滑动“窗口”。通过查看以下 REPL 交互,可以清楚地了解两者之间的差异

scala> val xs = List(1, 2, 3, 4, 5)
xs: List[Int] = List(1, 2, 3, 4, 5)
scala> val git = xs grouped 3
git: Iterator[List[Int]] = non-empty iterator
scala> git.next()
res3: List[Int] = List(1, 2, 3)
scala> git.next()
res4: List[Int] = List(4, 5)
scala> val sit = xs sliding 3
sit: Iterator[List[Int]] = non-empty iterator
scala> sit.next()
res5: List[Int] = List(1, 2, 3)
scala> sit.next()
res6: List[Int] = List(2, 3, 4)
scala> sit.next()
res7: List[Int] = List(3, 4, 5)

Iterable 类中的操作

是什么 做什么
抽象方法  
xs.iterator 一个 iterator,它生成 xs 中的每个元素。
其他迭代器  
xs.foreach(f) xs 的每个元素执行函数 f
xs.grouped(size) 一个迭代器,它生成此集合的固定大小“块”。
xs.sliding(size) 一个迭代器,它生成此集合中元素的固定大小滑动窗口。
添加  
xs.concat(ys)
(或 xs ++ ys)
一个集合,它由 xsys 的元素组成。ys 是一个 IterableOnce 集合,即 IterableIterator
映射  
xs.map(f) xs 中的每个元素应用函数 f 获得的集合。
xs.flatMap(f) xs 中的每个元素应用集合值函数 f 并连接结果获得的集合。
xs.collect(f) xs 中的每个元素应用部分函数 f 获得的集合,其中 f 是已定义的,并收集结果。
转换  
xs.to(SortedSet) 将集合工厂作为参数的通用转换操作。
xs.toList 将集合转换为列表。
xs.toVector 将集合转换为向量。
xs.toMap 将键/值对集合转换为映射。如果集合没有对作为元素,则调用此操作将导致静态类型错误。
xs.toSet 将集合转换为集合。
xs.toSeq 将集合转换为序列。
xs.toIndexedSeq 将集合转换为索引序列。
xs.toBuffer 将集合转换为缓冲区。
xs.toArray 将集合转换为数组。
复制  
xs copyToArray(arr, s, n) 将集合最多 n 个元素复制到数组 arr 中,从索引 s 开始。最后两个参数是可选的。
大小信息  
xs.isEmpty 测试集合是否为空。
xs.nonEmpty 测试集合是否包含元素。
xs.size 集合中的元素数量。
xs.knownSize 元素数量(如果计算该数量需要常量时间),否则为 -1
xs.sizeCompare(ys) 如果 xsys 集合短,则返回一个负值;如果 xsys 集合长,则返回一个正值;如果它们具有相同的大小,则返回 0。即使集合是无限的,此方法也能正常工作,例如 LazyList.from(1) sizeCompare List(1, 2) 返回一个正值。
xs.sizeCompare(n) 如果 xsn 短,则返回一个负值;如果 xsn 长,则返回一个正值;如果 xs 的大小为 n,则返回 0。即使集合是无限的,此方法也能正常工作,例如 LazyList.from(1) sizeCompare 42 返回一个正值。
xs.sizeIs < 42, xs.sizeIs != 42 等。 xs.sizeCompare(42) < 0xs.sizeCompare(42) != 0 等分别提供了更方便的语法。
元素检索  
xs.head 集合的第一个元素(或某个元素,如果未定义顺序)。
xs.headOption 选项值中的 xs 的第一个元素,如果 xs 为空,则为 None。
xs.last 集合的最后一个元素(或某个元素,如果未定义顺序)。
xs.lastOption 选项值中的 xs 的最后一个元素,如果 xs 为空,则为 None。
xs.find(p) 包含 xs 中满足 p 的第一个元素的选项,如果没有元素符合条件,则为 None
子集合  
xs.tail 集合的其余部分,不包括 xs.head
xs.init 集合的其余部分,不包括 xs.last
xs.slice(from, to) 一个集合,包含 xs 的某个索引范围内的元素(从 fromto,不包括 to)。
xs.take(n) 一个集合,包含 xs 的前 n 个元素(或一些任意 n 个元素,如果未定义顺序)。
xs.drop(n) 集合的其余部分,不包括 xs.take(n)
xs.takeWhile(p) 集合中元素的最长前缀,所有元素都满足 p
xs.dropWhile(p) 集合,不包含元素的最长前缀,所有元素都满足 p
xs.takeRight(n) 一个集合,包含 xs 的最后 n 个元素(或一些任意 n 个元素,如果未定义顺序)。
xs.dropRight(n) 集合的其余部分,不包括 xs.takeRight(n)
xs.filter(p) 一个集合,包含满足谓词 p 的 xs 元素。
xs.withFilter(p) 此集合的非严格筛选。后续对 mapflatMapforeachwithFilter 的调用将仅应用于 xs 中条件 p 为真的那些元素。
xs.filterNot(p) xs 中不满足谓词 p 的那些元素组成的集合。
细分  
xs.splitAt(n) 在某个位置拆分 xs,得到集合对 (xs take n, xs drop n)
xs.span(p) 根据谓词拆分 xs,得到集合对 (xs takeWhile p, xs.dropWhile p)
xs.partition(p) xs 拆分为一对集合;一个包含满足谓词 p 的元素,另一个包含不满足谓词的元素,得到集合对 (xs filter p, xs.filterNot p)
xs.groupBy(f) 根据判别函数 fxs 分区到一个集合映射中。
xs.groupMap(f)(g) 根据判别函数 fxs 分区到一个集合映射中,并对组中的每个元素应用转换函数 g
xs.groupMapReduce(f)(g)(h) 根据判别函数 fxs 进行分区,然后使用 h 函数合并将函数 g 应用到组中的每个元素的结果。
元素条件  
xs.forall(p) 布尔值,指示谓词 p 是否对 xs 的所有元素成立。
xs.exists(p) 布尔值,指示谓词 p 是否对 xs 中的某个元素成立。
xs.count(p) 满足谓词 pxs 中的元素数量。
折叠  
xs.foldLeft(z)(op) xs 的连续元素应用二元运算 op,从左到右,以 z 开始。
xs.foldRight(z)(op) xs 的连续元素应用二元运算 op,从右到左,以 z 结束。
xs.reduceLeft(op) 对非空集合 xs 的连续元素应用二元运算 op,从左到右。
xs.reduceRight(op) 对非空集合 xs 的连续元素应用二元运算 op,从右到左。
特定折叠  
xs.sum 集合 xs 中的数字元素值的总和。
xs.product 集合 xs 中的数字元素值的乘积。
xs.min 集合 xs 中的已排序元素值的最小值。
xs.max 集合 xs 中的已排序元素值的最大值。
xs.minOption min 类似,但如果 xs 为空,则返回 None
xs.maxOption max 类似,但如果 xs 为空,则返回 None
字符串  
xs.addString(b, start, sep, end) 将字符串添加到 StringBuilder b 中,该字符串显示 xs 中的所有元素,这些元素位于分隔符 sep 之间,并用字符串 startend 括起来。 startsepend 均为可选。
xs.mkString(start, sep, end) 将集合转换为字符串,该字符串显示 xs 中的所有元素,这些元素位于分隔符 sep 之间,并用字符串 startend 括起来。 startsepend 均为可选。
拉链  
xs.zip(ys) 来自 xsys 的相应元素对的集合。
xs.zipAll(ys, x, y) 来自 xsys 的相应元素对的集合,其中较短的序列通过附加元素 xy 扩展为与较长的序列匹配。
xs.zipWithIndex 来自 xs 的元素对及其索引的集合。
视图  
xs.view 生成 xs 的视图。

Iterable 下面的继承层次结构中,你会找到三个特征:SeqSetMapSeqMap 实现 PartialFunction 特征及其 applyisDefinedAt 方法,每个方法的实现方式不同。 SetSetOps 获取其 apply 方法。

对于序列,apply 是位置索引,其中元素始终从 0 开始编号。也就是说,Seq(1, 2, 3)(1) 给出 2。对于集合,apply 是成员资格测试。例如,Set('a', 'b', 'c')('b') 给出 true,而 Set()('a') 给出 false。最后,对于映射,apply 是选择。例如,Map('a' -> 1, 'b' -> 10, 'c' -> 100)('b') 给出 10

在以下内容中,我们将更详细地解释三种集合的每一种。

此页面的贡献者