Seq 特質代表序列。序列是一種可迭代的項目,具有 length
,其元素具有從 0
開始的固定索引位置。
序列上的操作,總結在下表中,屬於下列類別
- 索引和長度運算
apply
、isDefinedAt
、length
、indices
和lengthCompare
。對於Seq
,apply
運算表示索引;因此,類型為Seq[T]
的序列是一個部分函數,它採用Int
參數(一個索引),並產生類型為T
的序列元素。換句話說,Seq[T]
延伸PartialFunction[Int, T]
。序列的元素從零開始索引,直到序列的length
減一。序列上的length
方法是一般集合的size
方法的別名。lengthCompare
方法允許您比較序列的長度與 Int 或Iterable
,即使序列具有無限長度。 - 索引搜尋運算
indexOf
、lastIndexOf
、indexOfSlice
、lastIndexOfSlice
、indexWhere
、lastIndexWhere
、segmentLength
,它們傳回等於給定值或符合某個謂詞的元素的索引。 - 加法運算
prepended
、prependedAll
、appended
、appendedAll
、padTo
,它們傳回透過在序列的前面或後面新增元素而取得的新序列。 - 更新運算
updated
、patch
,它們傳回透過替換原始序列中某些元素而取得的新序列。 - 排序作業
sorted
、sortWith
、sortBy
,根據各種條件對序列元素進行排序。 - 反轉作業
reverse
、reverseIterator
,產生或處理序列元素的相反順序。 - 比較
startsWith
、endsWith
、contains
、containsSlice
、corresponds
、search
,關聯兩個序列或在序列中搜尋元素。 - 多重集合 作業
intersect
、diff
、distinct
、distinctBy
,對兩個序列的元素執行類似的集合作業或移除重複項。
如果序列是可變的,它另外提供一個有副作用的 update
方法,它允許更新序列元素。與 Scala 中一貫的做法一樣,seq(idx) = elem
這樣的語法只是 seq.update(idx, elem)
的簡寫,所以 update
免費提供了方便的賦值語法。請注意 update
和 updated
之間的區別。 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) |
從該索引開始的連續元素組成序列 ys 的 xs 的第一個索引。 |
xs.lastIndexOfSlice(ys) |
從該索引開始的連續元素組成序列 ys 的 xs 的最後一個索引。 |
xs.indexWhere(p) |
滿足 p 的 xs 中第一個元素的索引(有數種變體)。 |
xs.segmentLength(p, i) |
從 xs(i) 開始,滿足謂詞 p 的 xs 中元素的最長不中斷區段的長度。 |
新增 | |
xs.prepended(x) 或 x +: xs |
一個新的序列,由 x 前置於 xs 組成。 |
xs.prependedAll(ys) 或 ys ++: xs |
一個新的序列,由 ys 的所有元素前置於 xs 組成。 |
xs.appended(x) 或 xs :+ x |
一個新的序列,包含附加到 xs 的 x 。 |
xs.appendedAll(ys) 或 xs :++ ys |
一個新的序列,包含附加到 xs 的 ys 的所有元素。 |
xs.padTo(len, x) |
序列結果,從附加值 x 到 xs ,直到長度 len 為止。 |
更新 | |
xs.patch(i, ys, r) |
序列結果,從用修補程式 ys 取代 xs 的 r 元素開始,從 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) |
一個測試,用來檢查 xs 和 ys 是否包含相同元素,且順序相同。 |
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) |
測試 xs 和 ys 的對應元素是否符合二元謂詞 p 。 |
多重集合運算 | |
xs.intersect(ys) |
序列 xs 和 ys 的多重集合交集,會保留 xs 中元素的順序。 |
xs.diff(ys) |
序列 xs 和 ys 的多重集合差集,會保留 xs 中元素的順序。 |
xs.distinct |
不包含重複元素的 xs 子序列。 |
xs.distinctBy(f) |
套用轉換函數 f 後不包含重複元素的 xs 子序列。例如,List("foo", "bar", "quux").distinctBy(_.length) == List("foo", "quux") |
特質 Seq 有兩個子特質 LinearSeq 和 IndexedSeq。這些子特質並未為不可變分支新增任何新操作,但各自提供不同的效能特性:線性序列具有有效率的 head
和 tail
操作,而索引序列具有有效率的 apply
、length
和(如果可變)update
操作。常用的線性序列為 scala.collection.immutable.List
和 scala.collection.immutable.LazyList
。常用的索引序列為 scala.Array
和 scala.collection.mutable.ArrayBuffer
。 Vector
類別在索引存取和線性存取之間提供了一個有趣的折衷方案。它同時具有有效率的常數時間索引開銷和常數時間線性存取開銷。因此,向量是索引存取和線性存取並用的混合存取模式的良好基礎。您將在 稍後 進一步瞭解向量。
在可變分支上,IndexedSeq
新增了用於就地轉換其元素的操作(與轉換操作(例如 map
和 sort
)形成對比,這些操作在根 Seq
上可用,並會傳回新的集合實例)。
mutable.IndexedSeq 類別中的操作
是什麼 | 它做了什麼 |
---|---|
轉換 | |
xs.mapInPlace(f) |
透過將 f 函式套用至 xs 的每個元素,來轉換所有元素。 |
xs.sortInPlace() |
對 xs 集合進行排序。 |
xs.sortInPlaceWith(c) |
根據指定的比較函式 c 對 xs 集合進行排序。 |
xs.sortInPlaceBy(f) |
根據對函式 f 套用至每個元素的結果所定義的排序,對 xs 集合進行排序。 |
緩衝區
可變序列的一個重要子類別是 Buffer
。它們不僅允許更新現有元素,還允許新增、插入和移除元素。緩衝區支援的主要新方法包括 append
和 appendAll
(用於在尾端新增元素)、prepend
和 prependAll
(用於在前端新增元素)、insert
和 insertAll
(用於插入元素),以及 remove
、subtractOne
和 subtractAll
(用於移除元素)。這些操作總結在以下表格中。
兩個常用的緩衝區實作是 ListBuffer
和 ArrayBuffer
。顧名思義,ListBuffer
以 List
為後盾,並支援將其元素有效轉換為 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 具有相同元素的新緩衝區。 |