1. 程式人生 > >Scala筆記(一):Array,List,Tuple,Set,Map,Iterator

Scala筆記(一):Array,List,Tuple,Set,Map,Iterator

1. 陣列(Array)

陣列是程式設計中經常用到的資料結構,Scala中包括定長陣列(Array)和變長陣列(ArrayBuffer)。
定長陣列,就是長度不變的陣列,在Scala中使用Array進行宣告,如下:

val intArr = new Array[Int](2)   //定義長度為2的整型陣列,整型預設初始化為0,字串為null(空)
intArr(0) = 12  //給第1個數組元素賦值為12
intArr(1) = 45   //給第2個數組元素賦值為45
for (i <- 0 to 1) println(intArr(i))  //對陣列元素的引用,是圓括號,而不是方括號

Scala也提供了更加簡潔的陣列宣告和初始化方法,如下:

val intArr = Array(12,45)
val myStrArr = Array("BigData","Hadoop","Spark")
  --------------------
import scala.collection.mutable.ArrayBuffer //變長陣列的依賴包
val array = ArrayBuffer[String]() //空字串陣列
array += ("a","bc","def")  //增加元素

從上面程式碼可見,在定義時不需要給出陣列型別,Scala會自動根據提供的初始化資料來推斷出陣列的型別。

2. 列表(List)

在Spark學習中,經常會用到列表,宣告一個列表:

val intList = List(1,2,3)

列表有頭部和尾部的概念,可以使用intList.head來獲取上面定義的列表的頭部,值是1,使用intList.tail來獲取上面定義的列表的尾部,值是List(2,3),頭部是一個元素,而尾部則仍然是一個列表。
由於列表的頭部是一個元素,所以,可以使用::操作,在列表的頭部增加新的元素,得到一個新的列表:

val intList = List(1,2,3)
val intListOther = 0::intList

intListOther是一個新的列表List(0,1,2,3)。要構建一個列表List(1,2,3),實際上也可以採用下面的方式:

val intList =1::2::3::Nil  //Nil表示空列表。 

使用:::操作符對不同的列表進行連線得到新列表,如:

val intList1 = List(1,2)
val intList2 = List(3,4)
val intList3 = intList1:::intList2

Scala為列表提供了一些常用的方法,如實現求和,可以直接呼叫sum方法:

intList.sum

3. 元組(Tuple)

元組是不同型別的值的集合。元組和列表/陣列不同,列表/陣列中各個元素必須是相同型別,而元組可以包含不同型別的元素。
宣告一個名稱為tuple的元組):

val tuple = ("BigData",2015,45.0)
println(tuple._1)  //BigData
println(tuple._2)  //2015

宣告一個元組用圓括號把多個元組的元素包圍起來就可以,當需要訪問元組中的某個元素的值時,可以通過類似tuple._1、tuple._2這種方式就可以實現。

4. 集(Set)

集(set)是不重複元素的集合。列表中的元素是按照插入的先後順序來組織的,但是,”集”中的元素並不會記錄元素的插入順序,而是以“雜湊”方法對元素的值進行組織,所以,它允許你快速地找到某個元素。
集包括可變集和不可變集,預設情況下建立的是不可變集,通常使用不可變集。
用預設方式建立一個不可變集:

var mySet = Set("Hadoop","Spark")
mySet += "Scala"  //向mySet中增加新的元素
println(mySet.contains("Scala")) //true

上面宣告時,如果使用val,mySet += “Scala”執行時會報錯,所以需要宣告為var。
如果要宣告一個可變集,則需要引入scala.collection.mutable.Set包,具體如下(在Scala直譯器中執行):

import scala.collection.mutable.Set
val myMutableSet = Set("Database","BigData")
myMutableSet += "Cloud Computing"
println(myMutableSet)   // Set(BigData, Cloud Computing, Database)

上面程式碼中,宣告myMutableSet為val變數(不是var變數),由於是可變集,因此,可以正確執行myMutableSet += “Cloud Computing”,不會報錯。
注意:雖然可變集和不可變集都有新增或刪除元素的操作,但是,二者有區別:對不可變集進行操作,會產生一個新的集,原來的集不變。 而對可變集進行操作,改變的是該集本身。

5. 對映(Map)

在Scala中,對映(Map)是一系列鍵值對的集合,也就是,建立了鍵和值間對應關係。在對映中,所有的值,都可以通過鍵來獲取。
對映包括可變和不可變兩種,預設情況下建立的是不可變對映,如果需要建立可變對映,需要引入scala.collection.mutable.Map包。
建立一個不可變對映:

val university = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University")

如果要獲取對映中的值,可以通過鍵來獲取,如下:

println(university("XMU"))

上面程式碼通過”XMU”這個鍵,可以獲得值Xiamen University。
如果要檢查對映中是否包含某個值,可以使用contains方法,如下:

val xmu = if (university.contains("XMU")) university("XMU") else 0
println(xmu)

定義的不可變對映,無法更新對映中的元素,也無法增加新元素。如果要更新對映的元素,就需要定義一個可變的對映,如下:

import scala.collection.mutable.Map
val university2 = Map("XMU" -> "Xiamen University", "THU" -> "Tsinghua University","PKU"->"Peking University")
university2("XMU") = "Ximan University" //更新已有元素的值
university2("FZU") = "Fuzhou University" //新增新元素

也可以使用+=操作來新增新的元素:

university2 + = ("TJU"->"Tianjin University") //新增一個新元素
university2 + = ("SDU"->"Shandong University","WHU"->"Wuhan University") //同時新增兩個新元素

迴圈遍歷對映,是經常需要用到的操作,基本格式是:
for ((k,v) <- 對映) 語句塊

for ((k,v) <- university) printf("Code is : %s and name is: %s\n",k,v)

上面程式碼執行結果如下:

Code is : XMU and name is: Xiamen University
Code is : THU and name is: Tsinghua University
Code is : PKU and name is: Peking University

或者,也可以只遍歷對映中的k或者v,列印所有鍵或值:

for (k<-university.keys) println(k)
for (v<-university.values) println(v)

6. 迭代器(Iterator)

在Scala中,迭代器(Iterator)不是一個集合,但是,提供了訪問集合的一種方法。當構建一個集合需要很大的開銷時(比如把一個檔案的所有行都讀取記憶體),迭代器就可以發揮很好的作用。 迭代器包含兩個基本操作:next和hasNext。next可以返回迭代器的下一個元素,hasNext用於檢測是否還有下一個元素。
有了這兩個基本操作,就可以順利地遍歷迭代器中的所有元素。通常可以通過while迴圈或者for迴圈實現對迭代器的遍歷。
while迴圈如下:

val iter = Iterator("Hadoop","Spark","Scala")
while (iter.hasNext) {
    println(iter.next())
}

注意,上述操作執行結束後,迭代器會移動到末尾,就不能再使用了,如果繼續執行一次println(iter.next)就會報錯。程式碼中,使用iter.next和iter.next()都是可以的,但是,hasNext後面不能加括號。
for迴圈如下:

val iter = Iterator("Hadoop","Spark","Scala")
for (elem <- iter) {
    println(elem)
}