Scala 系列(五)—— 集合類型綜述

1、集合簡介

Scala中擁有多種集合類型,主要分爲可變的和不可變的集合兩大類:html

  • 可變集合: 能夠被修改。便可以更改,添加,刪除集合中的元素;
  • 不可變集合類:不能被修改。對集合執行更改,添加或刪除操做都會返回一個新的集合,而不是修改原來的集合。

2、集合結構

Scala中的大部分集合類都存在三類變體,分別位於scala.collection, scala.collection.immutable, scala.collection.mutable包中。還有部分集合類位於scala.collection.generic包下。java

  • scala.collection.immutable :包是中的集合是不可變的;
  • scala.collection.mutable :包中的集合是可變的;
  • scala.collection :包中的集合,既能夠是可變的,也能夠是不可變的。
val sortSet = scala.collection.SortedSet(1, 2, 3, 4, 5)
val mutableSet = collection.mutable.SortedSet(1, 2, 3, 4, 5)
val immutableSet = collection.immutable.SortedSet(1, 2, 3, 4, 5)

若是你僅寫了Set 而沒有加任何前綴也沒有進行任何import,則Scala默認採用不可變集合類。git

scala> Set(1,2,3,4,5)
res0: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)

3.1 scala.collection

scala.collection包中全部集合以下圖:程序員

3.2 scala.collection.mutable

scala.collection.mutable包中全部集合以下圖:es6

3.2 scala.collection.immutable

scala.collection.immutable包中全部集合以下圖:github

3、Trait Traversable

Scala中全部集合的頂層實現是Traversable 。它惟一的抽象方法是foreach數組

def foreach[U](f: Elem => U)

實現Traversable的集合類只須要實現這個抽象方法,其餘方法能夠從Traversable繼承。Traversable中的全部可用方法以下:緩存

方法 做用
Abstract Method:
xs foreach f 爲 xs 的每一個元素執行函數 f
Addition:
xs ++ ys 一個包含 xs 和 ys 中全部元素的新的集合。 ys 是一個 Traversable 或 Iterator。
Maps:
xs map f 對 xs 中每個元素應用函數 f,並返回一個新的集合
xs flatMap f 對 xs 中每個元素應用函數 f,最後將結果合併成一個新的集合
xs collect f 對 xs 中每個元素調用偏函數 f,並返回一個新的集合
Conversions:
xs.toArray 將集合轉化爲一個 Array
xs.toList 將集合轉化爲一個 List
xs.toIterable 將集合轉化爲一個 Iterable
xs.toSeq 將集合轉化爲一個 Seq
xs.toIndexedSeq 將集合轉化爲一個 IndexedSeq
xs.toStream 將集合轉化爲一個延遲計算的流
xs.toSet 將集合轉化爲一個 Set
xs.toMap 將一個(key, value)對的集合轉化爲一個Map。 若是當前集合的元素類型不是(key, value)對形式, 則報靜態類型錯誤。
Copying:
xs copyToBuffer buf 拷貝集合中全部元素到緩存 buf
xs copyToArray(arr,s,n) 從索引 s 開始,將集合中最多 n 個元素複製到數組 arr。 最後兩個參數是可選的。
Size info:
xs.isEmpty 判斷集合是否爲空
xs.nonEmpty 判斷集合是否包含元素
xs.size 返回集合中元素的個數
xs.hasDefiniteSize 若是 xs 具備有限大小,則爲真。
Element Retrieval:
xs.head 返回集合中的第一個元素(若是無序,則隨機返回)
xs.headOption 以 Option 的方式返回集合中的第一個元素, 若是集合爲空則返回 None
xs.last 返回集合中的最後一個元素(若是無序,則隨機返回)
xs.lastOption 以 Option 的方式返回集合中的最後一個元素, 若是集合爲空則返回 None
xs find p 以 Option 的方式返回知足條件 p 的第一個元素, 若是都不知足則返回 None
Subcollection:
xs.tail 除了第一個元素以外的其餘元素組成的集合
xs.init 除了最後一個元素以外的其餘元素組成的集合
xs slice (from, to) 返回給定索引範圍以內的元素組成的集合 (包含 from 位置的元素但不包含 to 位置的元素)
xs take n 返回 xs 的前n個元素組成的集合(若是無序,則返回任意n個元素)
xs drop n 返回 xs 的後n個元素組成的集合(若是無序,則返回任意n個元素)
xs takeWhile p 從第一個元素開始查找知足條件 p 的元素, 直到遇到一個不知足條件的元素,返回全部遍歷到的值。
xs dropWhile p 從第一個元素開始查找知足條件 p 的元素, 直到遇到一個不知足條件的元素,返回全部未遍歷到的值。
xs filter p 返回知足條件 p 的全部元素的集合
xs withFilter p 集合的非嚴格的過濾器。後續對 xs 調用方法 map、flatMap 以及 withFilter 都只用做於知足條件 p 的元素,而忽略其餘元素
xs filterNot p 返回不知足條件 p 的全部元素組成的集合
Subdivisions:
xs splitAt n 在給定位置拆分集合,返回一個集合對 (xs take n, xs drop n)
xs span p 根據給定條件拆分集合,返回一個集合對(xs takeWhile p, xs dropWhile p)。即遍歷元素,直到遇到第一個不符合條件的值則結束遍歷,將遍歷到的值和未遍歷到的值分別放入兩個集合返回。
xs partition p 按照篩選條件對元素進行分組
xs groupBy f 根據鑑別器函數 f 將 xs 劃分爲集合映射
Element Conditions:
xs forall p 判斷集合中全部的元素是否都知足條件 p
xs exists p 判斷集合中是否存在一個元素知足條件 p
xs count p xs 中知足條件 p 的元素的個數
Folds:
(z /: xs) (op) 以 z 爲初始值,從左到右對 xs 中的元素執行操做爲 op 的歸約操做
(xs :\ z) (op) 以 z 爲初始值,從右到左對 xs 中的元素執行操做爲 op 的歸約操做
xs.foldLeft(z) (op) 同 (z /: xs) (op)
xs.foldRight(z) (op) 同 (xs : z) (op)
xs reduceLeft op 從左到右對 xs 中的元素執行操做爲 op 的歸約操做
xs reduceRight op 從右到左對 xs 中的元素執行操做爲 op 的歸約操做
Specific Folds:
xs.sum 累計求和
xs.product 累計求積
xs.min xs 中的最小值
xs.max xs 中的最大值
String:
xs addString (b, start, sep, end) 向 StringBuilder b 中添加一個字符串, 該字符串包含 xs 的全部元素。start、seq 和 end 都是可選的,seq 爲分隔符,start 爲開始符號,end 爲結束符號。
xs mkString (start, seq, end) 將集合轉化爲一個字符串。start、seq 和 end 都是可選的,seq 爲分隔符,start 爲開始符號,end 爲結束符號。
xs.stringPrefix 返回 xs.toString 字符串開頭的集合名稱
Views:
xs.view 生成 xs 的視圖
xs view (from, to) 生成 xs上指定索引範圍內元素的視圖

下面爲部分方法的使用示例:app

scala> List(1, 2, 3, 4, 5, 6).collect { case i if i % 2 == 0 => i * 10 }
res0: List[Int] = List(20, 40, 60)

scala> List(1, 2, 3, 4, 5, 6).withFilter(_ % 2 == 0).map(_ * 10)
res1: List[Int] = List(20, 40, 60)

scala> (10 /: List(1, 2, 3)) (_ + _)
res2: Int = 16

scala> List(1, 2, 3, -4, 5) takeWhile (_ > 0)
res3: List[Int] = List(1, 2, 3)

scala> List(1, 2, 3, -4, 5) span (_ > 0)
res4: (List[Int], List[Int]) = (List(1, 2, 3),List(-4, 5))

scala> List(1, 2, 3).mkString("[","-","]")
res5: String = [1-2-3]

4、Trait Iterable

Scala中全部的集合都直接或者間接實現了Iterable特質,Iterable拓展自Traversable,並額外定義了部分方法:函數

方法 做用
Abstract Method:
xs.iterator 返回一個迭代器,用於遍歷 xs 中的元素, 與foreach遍歷元素的順序相同。
Other Iterators:
xs grouped size 返回一個固定大小的迭代器
xs sliding size 返回一個固定大小的滑動窗口的迭代器
Subcollections:
xs takeRigtht n 返回 xs 中最後 n 個元素組成的集合(若是無序,則返回任意 n 個元素組成的集合)
xs dropRight n 返回 xs 中除了最後 n 個元素外的部分
Zippers:
xs zip ys 返回 xs 和 ys 的對應位置上的元素對組成的集合
xs zipAll (ys, x, y) 返回 xs 和 ys 的對應位置上的元素對組成的集合。其中較短的序列經過附加元素 x 或 y 來擴展以匹配較長的序列。
xs.zipWithIndex 返回一個由 xs 中元素及其索引所組成的元素對的集合
Comparison:
xs sameElements ys 測試 xs 和 ys 是否包含相同順序的相同元素

全部方法的使用示例以下:

scala> List(1, 2, 3).iterator.reduce(_ * _ * 10)
res0: Int = 600

scala> List("a","b","c","d","e") grouped 2 foreach println
List(a, b)
List(c, d)
List(e)

scala> List("a","b","c","d","e") sliding 2 foreach println
List(a, b)
List(b, c)
List(c, d)
List(d, e)

scala>  List("a","b","c","d","e").takeRight(3)
res1: List[String] = List(c, d, e)

scala> List("a","b","c","d","e").dropRight(3)
res2: List[String] = List(a, b)

scala> List("a","b","c").zip(List(1,2,3))
res3: List[(String, Int)] = List((a,1), (b,2), (c,3))

scala> List("a","b","c","d").zipAll(List(1,2,3),"",4)
res4: List[(String, Int)] = List((a,1), (b,2), (c,3), (d,4))

scala> List("a","b","c").zipAll(List(1,2,3,4),"d","")
res5: List[(String, Any)] = List((a,1), (b,2), (c,3), (d,4))

scala> List("a", "b", "c").zipWithIndex
res6: List[(String, Int)] = List((a,0), (b,1), (c,2))

scala> List("a", "b") sameElements List("a", "b")
res7: Boolean = true

scala> List("a", "b") sameElements List("b", "a")
res8: Boolean = false

5、修改集合

當你想對集合添加或者刪除元素,須要根據不一樣的集合類型選擇不一樣的操做符號:

操做符 描述 集合類型
coll(k)
即coll.apply(k)
獲取指定位置的元素 Seq, Map
coll :+ elem
elem +: coll
向集合末尾或者集合頭增長元素 Seq
coll + elem
coll + (e1, e2, ...)
追加元素 Seq, Map
coll - elem
coll - (e1, e2, ...)
刪除元素 Set, Map, ArrayBuffer
coll ++ coll2
coll2 ++: coll
合併集合 Iterable
coll -- coll2 移除coll中包含的coll2中的元素 Set, Map, ArrayBuffer
elem :: lst
lst2 :: lst
把指定列表(lst2)或者元素(elem)添加到列表(lst)頭部 List
list ::: list2 合併List List
set | set2
set & set2
set &~ set2
並集、交集、差集 Set
coll += elem
coll += (e1, e2, ...)
coll ++= coll2
coll -= elem
coll -= (e1, e2, ...)
coll --= coll2
添加或者刪除元素,並將修改後的結果賦值給集合自己 可變集合
elem +=: coll
coll2 ++=: coll
在集合頭部追加元素或集合 ArrayBuffer

參考資料

  1. https://docs.scala-lang.org/overviews/collections/overview.html
  2. https://docs.scala-lang.org/overviews/collections/trait-traversable.html
  3. https://docs.scala-lang.org/overviews/collections/trait-iterable.html

更多大數據系列文章能夠參見我的 GitHub 開源項目: 程序員大數據入門指南

相關文章
相關標籤/搜索