過時公告
集合階層中從頂部算起的下一個特質是 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
,而這些方法只有在有迭代器時才能有效率地執行。它們總結在以下表格中。
可迭代特徵中的運算
它是什麼 | 它的作用 |
---|---|
抽象方法 | |
xs.iterator |
一個 iterator ,會產生 xs 中的每個元素,順序與 foreach 遍歷元素的順序相同。 |
其他迭代器 | |
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
。
以下,我們將更詳細地說明這三種集合。