在集合階層的頂端是特徵 Iterable
。此特徵中的所有方法都是根據抽象方法 iterator
定義的,此方法會逐一產生集合的元素。
def iterator: Iterator[A]
實作 Iterable
的集合類別只需要定義這個方法;所有其他方法都可以從 Iterable
繼承。
Iterable
也定義許多具體方法,所有方法都列在以下表格中。這些方法分為下列類別
- 新增,
concat
,將兩個集合串接在一起,或將反覆運算器的所有元素串接至集合。 - 對應 操作
map
、flatMap
和collect
,透過對集合元素套用某些函數產生新的集合。 - 轉換
to
、toList
、toVector
、toMap
、toSet
、toSeq
、toIndexedSeq
、toBuffer
、toArray
,將Iterable
集合轉換成更具體的內容。如果目標是可變集合 (to(collection.mutable.X)
、toArray
、toBuffer
),會透過複製原始元素建立新的集合。如果集合的執行時間類型已符合要求的集合類型,所有這些轉換都會傳回未變更的接收器引數。例如,對清單套用toList
會產生清單本身。 - 複製操作
copyToArray
。顧名思義,這會將集合元素複製到陣列。 - 大小資訊運算
isEmpty
、nonEmpty
、size
、knownSize
、sizeIs
。在某些情況下,集合的元素數量可能需要進行遍歷(例如List
)。在其他情況下,集合可能具有無限個元素(例如LazyList.from(1)
)。 - 元素擷取運算
head
、last
、headOption
、lastOption
和find
。這些運算會選取集合的第一個或最後一個元素,或是符合條件的第一個元素。不過,請注意,並非所有集合都對「第一個」和「最後一個」有明確的定義。例如,雜湊集合可能會根據元素的雜湊金鑰來儲存元素,而這些金鑰可能會在每次執行時改變。在這種情況下,雜湊集合的「第一個」元素也可能因程式的每次執行而不同。如果集合總是按照相同的順序產生其元素,則該集合為已排序。大多數集合都是已排序的,但有些集合(例如雜湊集合)則不是,捨棄排序可以獲得一些額外的效率。排序通常對於提供可重製的測試和協助除錯至關重要。這就是 Scala 集合為所有集合類型提供已排序替代方案的原因。例如,HashSet
的已排序替代方案為LinkedHashSet
。 - 子集合擷取操作
tail
、init
、slice
、take
、drop
、takeWhile
、dropWhile
、filter
、filterNot
、withFilter
。這些都會傳回一些由索引範圍或一些謂詞識別的子集合。 - 細分操作
splitAt
、span
、partition
、partitionMap
、groupBy
、groupMap
、groupMapReduce
,這些會將此集合的元素拆分成數個子集合。 - 元素測試
exists
、forall
、count
,這些會使用指定的謂詞測試集合元素。 - 摺疊
foldLeft
、foldRight
、reduceLeft
、reduceRight
,這些會對相繼的元素套用二元運算。 - 特定摺疊
sum
、product
、min
、max
,這些會作用於特定類型(數值或可比較的)的集合。 - 字串 操作
mkString
和addString
,這些提供了將集合轉換為字串的替代方法。 - 檢視 操作:檢視是延遲評估的集合。您將在 稍後 進一步瞭解檢視。
在 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 中的運算
功能 | 用途 |
---|---|
抽象方法 | |
xs.iterator |
一個 iterator ,會產生 xs 中的每個元素。 |
其他迭代器 | |
xs.foreach(f) |
對 xs 的每個元素執行函式 f 。 |
xs.grouped(size) |
一個迭代器,會產生這個集合的固定大小「區塊」。 |
xs.sliding(size) |
一個迭代器,會在這個集合中產生一個滑動的固定大小視窗。 |
加法 | |
xs.concat(ys) (或 xs ++ ys ) |
一個集合,包含 xs 和 ys 的元素。ys 是 IterableOnce 集合,也就是 Iterable 或 Iterator。 |
映射 | |
xs.map(f) |
從將函數 f 套用至 xs 中每個元素所取得的集合。 |
xs.flatMap(f) |
從將集合值函數 f 套用至 xs 中每個元素並串接結果所取得的集合。 |
xs.collect(f) |
從將部分函數 f 套用至 xs 中每個已定義的元素並收集結果所取得的集合。 |
轉換 | |
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) |
如果 xs 短於 ys 集合,則傳回負值;如果較長,則傳回正值;如果大小相同,則傳回 0 。即使集合為無限大,此方法也適用,例如 LazyList.from(1) sizeCompare List(1, 2) 會傳回正值。 |
xs.sizeCompare(n) |
如果 xs 短於 n ,則傳回負值;如果較長,則傳回正值;如果大小為 n ,則傳回 0 。即使集合為無限大,此方法也適用,例如 LazyList.from(1) sizeCompare 42 會傳回正值。 |
xs.sizeIs < 42 、xs.sizeIs != 42 等。 |
分別提供 xs.sizeCompare(42) < 0 、xs.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 中某個索引範圍內的元素(從 from 到 to ,但不包含 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) |
此集合的非嚴格篩選器。後續呼叫 map 、flatMap 、foreach 和 withFilter 將只套用至條件 p 為真的 xs 元素。 |
xs.filterNot(p) |
不滿足謂詞 p 的 xs 元素的集合。 |
細分 | |
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) |
根據辨別函數 f 將 xs 分割為集合的映射。 |
xs.groupMap(f)(g) |
根據辨別函數 f 將 xs 分割為集合的映射,並將轉換函數 g 套用至群組中的每個元素。 |
xs.groupMapReduce(f)(g)(h) |
根據辨別函數 f 分割 xs ,然後使用 h 函數結合將函數 g 套用至群組中每個元素的結果。 |
元素條件 | |
xs.forall(p) |
布林值,表示謂詞 p 是否對 xs 的所有元素成立。 |
xs.exists(p) |
布林值,表示謂詞 p 是否對 xs 中的某個元素成立。 |
xs.count(p) |
滿足謂詞 p 的 xs 中元素的數量。 |
摺疊 | |
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 ,並封裝在字串 start 和 end 中。 start 、sep 、end 均為選用。 |
xs.mkString(start, sep, end) |
將集合轉換為字串,顯示 xs 中所有元素,分隔符號為 sep ,並封裝在字串 start 和 end 中。 start 、sep 、end 均為選用。 |
拉鍊 | |
xs.zip(ys) |
來自 xs 和 ys 中對應元素的配對集合。 |
xs.zipAll(ys, x, y) |
來自 xs 和 ys 中對應元素的配對集合,其中較短的序列會透過附加元素 x 或 y 來延伸,以符合較長的序列。 |
xs.zipWithIndex |
與其索引一起收集 xs 中的元素對。 |
檢視 | |
xs.view |
產生 xs 的檢視。 |
在 Iterable
下的繼承層級中,您會找到三個特質:Seq、Set 和 Map。 Seq
和 Map
實作 PartialFunction 特質,以及其 apply
和 isDefinedAt
方法,每個方法的實作方式不同。 Set
從 SetOps 取得其 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
。
以下,我們將更詳細地說明三種集合的每種類型。