集合

特徵 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 的元素。ysIterableOnce 集合,也就是 IterableIterator
映射  
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 < 42xs.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 將只套用至條件 p 為真的 xs 元素。
xs.filterNot(p) 不滿足謂詞 pxs 元素的集合。
細分  
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) 根據辨別函數 f 分割 xs,然後使用 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

以下,我們將更詳細地說明三種集合的每種類型。

此頁面的貢獻者