我們?cè)谇懊娼榻B Scala 編程時(shí)對(duì) Scala 庫提供的函數(shù)庫沒有介紹,Scala 支持的集合類型比如 List,Set,Map,Array 功能非常強(qiáng)大,如果你之前用過 C# 的 LINQ,基本上 LINQ 支持的功能 Scala 的集合類型都支持,很多以前需要循環(huán)來實(shí)現(xiàn)的,在 Scala 中可能只需要一行就可以實(shí)現(xiàn),有時(shí)間我們專門來介紹下 Scala 支持的集合類型。
本篇對(duì) Scala 中最常用的 List 類型做個(gè)概要的介紹。
List 和 Array 非常相像,但有兩個(gè)重要的不同點(diǎn),List 是不可變的(immutable),也就是 List 創(chuàng)建后,不可以修改。List 具有遞歸的結(jié)構(gòu)(也就是鏈接表結(jié)構(gòu))而數(shù)組不是。
和數(shù)組一樣,List 中的元素必須是同類型的。下面我們來看看如何構(gòu)造一個(gè) List 對(duì)象:
scala> val fruit = List("apple","oranges","pears")
fruit: List[String] = List(apple, oranges, pears)
scala> val empty=List()
empty: List[Nothing] = List()
scala> val fruit = "apple" :: "orange" :: "pears" :: Nil
fruit: List[String] = List(apple, orange, pears)
scala> val empty = Nil
empty: scala.collection.immutable.Nil.type = List()
scala> val nums = 1 :: 2 :: 3 :: 4 :: Nil
nums: List[Int] = List(1, 2, 3, 4)
List 可以通過構(gòu)造函數(shù)創(chuàng)建,也可以通過:: 連接每個(gè)元素,::是右結(jié)合的,在通過::構(gòu)造列表時(shí),需要在最右邊使用 Nil,這樣編譯器才知道構(gòu)造一個(gè) List,因?yàn)樽址?String 本身不支持::操作。
head 取 List 的首元素 tail 取除首元素之外的 List 的其它元素 isEmpty 判斷 List 是否為空
scala> empty.isEmpty
res0: Boolean = true
scala> fruit.head
res1: String = apple
scala> fruit.tail
res2: List[String] = List(orange, pears)
可以使用模式對(duì)多個(gè)元素進(jìn)行賦值
scala> val List(a,b,c)=fruit
a: String = apple
b: String = orange
c: String = pears
scala> val a::b::c = fruit
a: String = apple
b: String = orange
c: List[String] = List(pears)
合并兩個(gè) List 可以使用 :::操作符,這個(gè)操作符也是右連接的:
scala> List(1,2) ::: List (3,4,5)
res3: List[Int] = List(1, 2, 3, 4, 5)
scala> List() ::: List (1,2,3)
res4: List[Int] = List(1, 2, 3)
使用 reverse 可以逆轉(zhuǎn) List 中元素的順序:
scala> List(1,2,3,4,5,6).reverse
res6: List[Int] = List(6, 5, 4, 3, 2, 1)
drop,take 操作為 head,tail (和 init)的一般形式, xs take n 返回 List 的前 n 個(gè)元素,xs drop n返回除前 n 個(gè)元素的 List 余下的元素,如果 n 比 List 全長要大,則返回空 List。 splitAt 可以把一個(gè)List在指定位置分成兩個(gè) List xs spliatAt n 和 (xs taken n, xs drop n)等價(jià)
scala> val abcde =List ('a','b','c','d','e')
abcde: List[Char] = List(a, b, c, d, e)
scala> abcde take 2
res8: List[Char] = List(a, b)
scala> abcde drop 2
res9: List[Char] = List(c, d, e)
scala> abcde splitAt 2
res10: (List[Char], List[Char]) = (List(a, b),List(c, d, e))
flatten 可以展開嵌套的 List 為一個(gè)單個(gè) List,比如:
scala> List(List(1,2),List(3,4),List(5,6)).flatten
res11: List[Int] = List(1, 2, 3, 4, 5, 6)
zip 和從兩個(gè) List 分別去對(duì)應(yīng)的元素,組成二元組,構(gòu)成新的 List
scala> abcde.indices zip abcde
res12: scala.collection.immutable.IndexedSeq[(Int, Char)] = Vector((0,a), (1,b), (2,c), (3,d), (4,e))
scala> abcde zip List(1,2,3)
res13: List[(Char, Int)] = List((a,1), (b,2), (c,3))
unzip 執(zhí)行相反的操作。
scala> val zipped=abcde.zipWithIndex
zipped: List[(Char, Int)] = List((a,0), (b,1), (c,2), (d,3), (e,4))
scala> zipped.unzip
res14: (List[Char], List[Int]) = (List(a, b, c, d, e),List(0, 1, 2, 3, 4))
toString 顯示 List 的正規(guī)字符表示。 mkString 可以格式化 List 顯示
scala> abcde.toString
res15: String = List(a, b, c, d, e)
scala> abcde.mkString("[",",","]")
res16: String = [a,b,c,d,e]
scala> abcde mkString ""
res17: String = abcde
scala> abcde mkString("\n")
res19: String =
a
b
c
d
e
map 可以對(duì) List 的每個(gè)元素逐個(gè)應(yīng)用某個(gè)函數(shù),轉(zhuǎn)換成另外一個(gè)列表
scala> List(1,2,3) map (_ + 1)
res20: List[Int] = List(2, 3, 4)
scala> val words= List("the","quick","brown","fox")
words: List[String] = List(the, quick, brown, fox)
scala> words map (_.length)
res21: List[Int] = List(3, 5, 5, 3)
flatMap 和 map 類似,但它使用的函數(shù)需要返回一個(gè)列表,然后它把這個(gè)函數(shù)用于到 List 的每個(gè)元素,然后合并列表
scala> words map (_.toList)
res22: List[List[Char]] = List(List(t, h, e), List(q, u, i, c, k), List(b, r, o, w, n), List(f, o, x))
scala> (words map (_.toList)).flatten
res23: List[Char] = List(t, h, e, q, u, i, c, k, b, r, o, w, n, f, o, x)
scala> words flatMap (_.toList)
res24: List[Char] = List(t, h, e, q, u, i, c, k, b, r, o, w, n, f, o, x)
filter, partition,find, takeWhile, dropWhile ,span 可以用來根據(jù)條件過濾列表的元素,構(gòu)成新列表
scala> List(1,2,3,4,5) filter (_ % 2==0)
res25: List[Int] = List(2, 4)
scala> List(1,2,3,4,5) partition (_ % 2==0)
res27: (List[Int], List[Int]) = (List(2, 4),List(1, 3, 5))