过时通知
集合层次结构中从顶部开始的下一个特性是 Iterable。此特性中的所有方法都根据抽象方法 iterator 定义,该方法逐个生成集合的元素。特性 Traversable 中的 foreach 方法在 Iterable 中根据 iterator 实现。以下是实际实现
def foreach[U](f: Elem => U): Unit = {
val it = iterator
while (it.hasNext) f(it.next())
}
相当多的 Iterable 子类重写了 Iterable 中的此 foreach 标准实现,因为它们可以提供更有效的实现。请记住,foreach 是 Traversable 中所有操作实现的基础,因此它的性能很重要。
Iterable 中还有另外两种返回迭代器的函数:grouped 和 sliding。但是,这些迭代器不会返回单个元素,而是返回原始集合中元素的整个子序列。这些子序列的最大大小作为参数提供给这些方法。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 还向 Traversable 添加了一些其他方法,这些方法只有在有迭代器时才能有效实现。它们总结在以下表格中。
特性 Iterable 中的操作
| 它是什么 | 它做什么 |
|---|---|
| 抽象方法 | |
xs.iterator |
一个iterator,它以与foreach遍历元素相同的顺序,产生xs中的每个元素。 |
| 其他迭代器 | |
xs grouped size |
一个迭代器,它产生此集合的固定大小的“块”。 |
xs sliding size |
一个迭代器,它产生此集合中元素的滑动固定大小窗口。 |
| 子集合 | |
xs takeRight n |
一个集合,它包含xs的最后n个元素(或者,如果没有定义顺序,则包含一些任意的n个元素)。 |
xs dropRight n |
除了xs takeRight n之外的集合的其余部分。 |
| 拉链 | |
xs zip ys |
一个可迭代的xs和ys中相应元素对。 |
xs zipAll (ys, x, y) |
一个可迭代的xs和ys中相应元素对,其中较短的序列通过附加元素x或y扩展为与较长的序列匹配。 |
xs.zipWithIndex |
一个可迭代的xs中元素与其索引的对。 |
| 比较 | |
xs sameElements ys |
一个测试,用于测试xs和ys是否按相同顺序包含相同的元素 |
在Iterable下面的继承层次结构中,你会发现三个特征:Seq、Set和Map。Seq和Map实现PartialFunction特征及其apply和isDefinedAt方法,每个方法的实现方式不同。Set从GenSetLike获取其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。
在下面,我们将更详细地解释每种类型的集合。