Scala的集合體繫結構
Scala 中的集合體系主要包括:Iterable、Seq、Set、Map。
其中 Iterable 是所有集合 trait 的根 trait。這個結構與Java的集合體系非常相似。
Scala 中的集合是分成可變和不可變兩類集合的,其中可變集合就是說,集合的元素可以動態修改,而不可變集合的元素在初始化之後,就無法修改了。分別對應 scala.collection.mutable 和 scala.collection.immutable 兩個包。
Seq 下包含了 Range、ArrayBuffer、List 等子 trait。其中Range 就代表了一個序列,通常可以使用 “1 to 10” 這種語法來產生一個 Range。 ArrayBuffer 就類似於 Java中的 ArrayList。
List
List 代表一個不可變的列表。
List 的創建:
val list = List(1,2,3,4)
List 有 head 和 tail,head 代表List 的第一個元素,tail 代表第一個元素之後的所有元素。
val list = List(1,2,3,4)
list.head
list.tail
List 有特殊的 :: 操作符,可以用於將 head 和 tail 合併成一個 List。
val list = List(1,2,3,4)
0::list
// List(0,1,2,3,4)
1::list
// List(1,1,2,3,4)
如果一個 List 只有一個元素,那麼它的 head 就是這個元素,它的tail是Nil。
val list = List(1)
list.head
// Int = 1
list.tail
// List[Int] = List()
案例:用遞歸函數來給 List 中每個元素都加上指定前綴並打印(加上指的是打印出的效果)。
def func(prefix:String, list:List[Int]){
if(list != Nil){
println(prefix + list.head)
func(prefix,list.tail)
}
}
LinkedList
LinkedList 代表一個可變的列表,使用 elem 可以引用其頭部,使用next 可以引用其尾部。
val list = scala.collection.mutable.LinkedList(1,2,3,4,5)
list.elem
// Int = 1
list.next
// scala.collection.mutable.LinkedList[Int] = LinkedList(2, 3, 4, 5)
案例:使用 while 循環將LinkedList 中的每個元素都乘以 2 。
val list = scala.collection.mutable.LinkedList(1,2,3,4,5)
var currentList = list
while(currentList != Nil){
currentList.elem = currentList.elem * 2
currentList = currentList.next
}
案例:使用 while 循環將LinkedList 中,從第一個元素開始,每隔一個元素,乘以 2 。
Set
Set 代表一個沒有重複元素的集合,將重複元素加入 Set 是沒有用的。
而且 Set 是不保證插入順序的,也就是說,Set 中的元素是亂序的。
val s = new scala.collection.mutable.HashSet[Int]();
s += 1
s += 2
s += 5
LinkedHashSet 會用一個鏈表維護插入順序。
val s = new scala.collection.mutable.LinkedHashSet[Int]()
s += 1
s += 2
s += 5
SrotedSet 會自動根據 key 來進行排序。
val s = scala.collection.mutable.SortedSet("orange", "apple", "banana")
// 按字典序排序
val ss = scala.collection.mutable.SortedSet(4,2,3)
// 默認是從小到大
集合的函數式編程
集合的函數式編程非常非常非常之重要!!!
Scala 的集合類的 map、flatMap、reduce、reduceLeft、foreach 等這些函數,就是高階函數,因爲可以接收其他函數作爲參數。
高階函數的使用,也是 Scala 與Java 的不同。因爲 Java 裏面是沒有函數式編程的,也肯定沒有高階函數,也肯定無法直接將函數傳入一個方法,或者讓一個方法返回一個函數。
// map 練習:爲List中每個元素都添加一個前綴
List("Li", "Chy", "Ln").map("name is " + _)
// faltMap 練習:將List中的多行句子拆分成單詞
List("Hello World", "Like You").flatMap(_.split(" "))
// foreach 練習:打印 List 中的每個單詞
List("I","have","a","girlfriend").foreach(println(_))
// zip 練習:對學生姓名和學生成績進行關聯
List("Li", "Hcy", "chy").zip(List(100, 100, 99))
函數式編程綜合案例:統計多個文本內的單詞總數
val line1 = scala.io.Source.fromFile("C://Users//12895//Desktop//text1.txt").mkString
val line2 = scala.io.Source.fromFile("C://Users//12895//Desktop//text2.txt").mkString
// 這裏的文本中單詞都是空格分開的。
val lines = List(line1,line2)
lines.flatMap(_.split(" ")).map((_,1)).map(_._2).reduceLeft(_+_)
// lines.flatMap(_.split(" ")) 以空格爲分隔符,分割單詞
// lines.flatMap(_.split(" ")).map((_,1)) 每個單詞計數
// lines.flatMap(_.split(" ")).map((_,1)).map(_._2) 拿出來個數
// lines.flatMap(_.split(" ")).map((_,1)).map(_._2).reduceLeft(_+_) 依次相加