集合

序列特質 Seq、IndexedSeq 和 LinearSeq

語言

Seq 特質代表序列。序列是一種可迭代的項目,具有 length,其元素具有從 0 開始的固定索引位置。

序列上的操作,總結在下表中,屬於下列類別

  • 索引和長度運算 applyisDefinedAtlengthindiceslengthCompare。對於 Seqapply 運算表示索引;因此,類型為 Seq[T] 的序列是一個部分函數,它採用 Int 參數(一個索引),並產生類型為 T 的序列元素。換句話說,Seq[T] 延伸 PartialFunction[Int, T]。序列的元素從零開始索引,直到序列的 length 減一。序列上的 length 方法是一般集合的 size 方法的別名。lengthCompare 方法允許您比較序列的長度與 Int 或 Iterable,即使序列具有無限長度。
  • 索引搜尋運算 indexOflastIndexOfindexOfSlicelastIndexOfSliceindexWherelastIndexWheresegmentLength,它們傳回等於給定值或符合某個謂詞的元素的索引。
  • 加法運算 prependedprependedAllappendedappendedAllpadTo,它們傳回透過在序列的前面或後面新增元素而取得的新序列。
  • 更新運算 updatedpatch,它們傳回透過替換原始序列中某些元素而取得的新序列。
  • 排序作業 sortedsortWithsortBy,根據各種條件對序列元素進行排序。
  • 反轉作業 reversereverseIterator,產生或處理序列元素的相反順序。
  • 比較 startsWithendsWithcontainscontainsSlicecorrespondssearch,關聯兩個序列或在序列中搜尋元素。
  • 多重集合 作業 intersectdiffdistinctdistinctBy,對兩個序列的元素執行類似的集合作業或移除重複項。

如果序列是可變的,它另外提供一個有副作用的 update 方法,它允許更新序列元素。與 Scala 中一貫的做法一樣,seq(idx) = elem 這樣的語法只是 seq.update(idx, elem) 的簡寫,所以 update 免費提供了方便的賦值語法。請注意 updateupdated 之間的區別。 update 就地變更序列元素,並且僅對可變序列可用。 updated 對所有序列都可用,並且始終返回一個新序列,而不是修改原始序列。

Seq 類中的操作

是什麼 它做了什麼
索引和長度  
xs(i) (或寫成 xs.apply(i))。索引 i 處的 xs 元素。
xs.isDefinedAt(i) 測試 i 是否包含在 xs.indices 中。
xs.length 序列的長度(與 size 相同)。
xs.lengthCompare(n) 如果 xs 短於 n,則返回 -1,如果它更長,則返回 +1,如果它的長度為 n,則返回 0。即使序列是無限的,此方法也能正常工作,例如 LazyList.from(1).lengthCompare(42) 會返回一個正值。
xs.indices 索引範圍 xs,從 0 延伸至 xs.length - 1
索引搜尋  
xs.indexOf(x) xs 中第一個等於 x 的元素索引(有數種變體)。
xs.lastIndexOf(x) xs 中最後一個等於 x 的元素索引(有數種變體)。
xs.indexOfSlice(ys) 從該索引開始的連續元素組成序列 ysxs 的第一個索引。
xs.lastIndexOfSlice(ys) 從該索引開始的連續元素組成序列 ysxs 的最後一個索引。
xs.indexWhere(p) 滿足 p 的 xs 中第一個元素的索引(有數種變體)。
xs.segmentLength(p, i) xs(i) 開始,滿足謂詞 pxs 中元素的最長不中斷區段的長度。
新增  
xs.prepended(x)
x +: xs
一個新的序列,由 x 前置於 xs 組成。
xs.prependedAll(ys)
ys ++: xs
一個新的序列,由 ys 的所有元素前置於 xs 組成。
xs.appended(x)
xs :+ x
一個新的序列,包含附加到 xsx
xs.appendedAll(ys)
xs :++ ys
一個新的序列,包含附加到 xsys 的所有元素。
xs.padTo(len, x) 序列結果,從附加值 xxs,直到長度 len 為止。
更新  
xs.patch(i, ys, r) 序列結果,從用修補程式 ys 取代 xsr 元素開始,從 i 開始。
xs.updated(i, x) 一個 xs 的副本,其中索引 i 的元素被 x 取代。
xs(i) = x (或寫出來,xs.update(i, x),僅適用於 mutable.Seq)。將 xs 在索引 i 的元素變更為 x
排序  
xs.sorted 一個新的序列,透過使用 xs 元素類型的標準順序,對 xs 的元素進行排序而取得。
xs.sortWith(lt) 一個新的序列,透過使用 lt 作為比較運算,對 xs 的元素進行排序而取得。
xs.sortBy(f) 透過對 xs 的元素進行排序而取得的新序列。兩個元素之間的比較是透過對兩個元素套用函數 f,並比較結果來進行。
反轉  
xs.reverse 一個包含 xs 的元素,並以反向順序排列的序列。
xs.reverseIterator 一個迭代器,會以反向順序產生 xs 的所有元素。
比較  
xs.sameElements(ys) 一個測試,用來檢查 xsys 是否包含相同元素,且順序相同。
xs.startsWith(ys) 測試 xs 是否以序列 ys 開頭(有多種變體)。
xs.endsWith(ys) 測試 xs 是否以序列 ys 結尾(有多種變體)。
xs.contains(x) 測試 xs 是否有一個元素等於 x
xs.search(x) 測試已排序的序列 xs 是否有一個元素等於 x,可能比 xs.contains(x) 更有效率。
xs.containsSlice(ys) 測試 xs 是否有一個連續子序列等於 ys
xs.corresponds(ys)(p) 測試 xsys 的對應元素是否符合二元謂詞 p
多重集合運算  
xs.intersect(ys) 序列 xsys 的多重集合交集,會保留 xs 中元素的順序。
xs.diff(ys) 序列 xsys 的多重集合差集,會保留 xs 中元素的順序。
xs.distinct 不包含重複元素的 xs 子序列。
xs.distinctBy(f) 套用轉換函數 f 後不包含重複元素的 xs 子序列。例如,List("foo", "bar", "quux").distinctBy(_.length) == List("foo", "quux")

特質 Seq 有兩個子特質 LinearSeqIndexedSeq。這些子特質並未為不可變分支新增任何新操作,但各自提供不同的效能特性:線性序列具有有效率的 headtail 操作,而索引序列具有有效率的 applylength 和(如果可變)update 操作。常用的線性序列為 scala.collection.immutable.Listscala.collection.immutable.LazyList。常用的索引序列為 scala.Arrayscala.collection.mutable.ArrayBufferVector 類別在索引存取和線性存取之間提供了一個有趣的折衷方案。它同時具有有效率的常數時間索引開銷和常數時間線性存取開銷。因此,向量是索引存取和線性存取並用的混合存取模式的良好基礎。您將在 稍後 進一步瞭解向量。

在可變分支上,IndexedSeq 新增了用於就地轉換其元素的操作(與轉換操作(例如 mapsort)形成對比,這些操作在根 Seq 上可用,並會傳回新的集合實例)。

mutable.IndexedSeq 類別中的操作

是什麼 它做了什麼
轉換  
xs.mapInPlace(f) 透過將 f 函式套用至 xs 的每個元素,來轉換所有元素。
xs.sortInPlace() xs 集合進行排序。
xs.sortInPlaceWith(c) 根據指定的比較函式 cxs 集合進行排序。
xs.sortInPlaceBy(f) 根據對函式 f 套用至每個元素的結果所定義的排序,對 xs 集合進行排序。

緩衝區

可變序列的一個重要子類別是 Buffer。它們不僅允許更新現有元素,還允許新增、插入和移除元素。緩衝區支援的主要新方法包括 appendappendAll(用於在尾端新增元素)、prependprependAll(用於在前端新增元素)、insertinsertAll(用於插入元素),以及 removesubtractOnesubtractAll(用於移除元素)。這些操作總結在以下表格中。

兩個常用的緩衝區實作是 ListBufferArrayBuffer。顧名思義,ListBufferList 為後盾,並支援將其元素有效轉換為 List,而 ArrayBuffer 則以陣列為後盾,且可以快速轉換為陣列。

Buffer 類別中的操作

是什麼 它做了什麼
新增  
buf.append(x)
buf += x
將元素 x 附加到緩衝區,並將 buf 本身作為結果傳回。
buf.appendAll(xs)
buf ++= xs
xs 中的所有元素附加到緩衝區。
buf.prepend(x)
x +=: buf
將元素 x 預先附加到緩衝區。
buf.prependAll(xs)
xs ++=: buf
xs 中的所有元素預先附加到緩衝區。
buf.insert(i, x) 在緩衝區的索引 i 處插入元素 x
buf.insertAll(i, xs) 在緩衝區的索引 i 處插入 xs 中的所有元素。
buf.padToInPlace(n, x) 將元素 x 附加到緩衝區,直到它總共有 n 個元素。
移除  
buf.subtractOne(x)
buf -= x
從緩衝區中移除元素 x
buf.subtractAll(xs)
buf --= xs
從緩衝區中移除 xs 中的元素。
buf.remove(i) 從緩衝區中移除索引 i 處的元素。
buf.remove(i, n) 從緩衝區中移除從索引 i 開始的 n 個元素。
buf.trimStart(n) 移除緩衝區中開頭 n 個元素。
buf.trimEnd(n) 移除緩衝區中最後 n 個元素。
buf.clear() 移除緩衝區中所有元素。
替換  
buf.patchInPlace(i, xs, n) 替換緩衝區中從索引 i 開始的 (最多) n 個元素為 xs 中的元素。
複製  
buf.clone() 一個與 buf 具有相同元素的新緩衝區。

此頁面的貢獻者