过时通知
集合层次结构中从顶部开始的下一个特性是 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
。
在下面,我们将更详细地解释每种类型的集合。