Spark大數(shù)據(jù)編程基礎(chǔ)(Scala版)_第1頁
Spark大數(shù)據(jù)編程基礎(chǔ)(Scala版)_第2頁
Spark大數(shù)據(jù)編程基礎(chǔ)(Scala版)_第3頁
Spark大數(shù)據(jù)編程基礎(chǔ)(Scala版)_第4頁
Spark大數(shù)據(jù)編程基礎(chǔ)(Scala版)_第5頁
已閱讀5頁,還剩232頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、Spark大數(shù)據(jù)編程基礎(chǔ)(Scala版)Spark大數(shù)據(jù)編程基礎(chǔ)(Scala版)第三章 Scala語言基礎(chǔ) 在Spark中可以使用Scala、Java、Python語言進行分布式程序開發(fā),但Spark提供的首選語言是Scala。作為Apache Spark的原生開發(fā)語言, Scala語言在大數(shù)據(jù)處理領(lǐng)域受到廣泛關(guān)注。主要內(nèi)容3.1 Scala簡介3.2 變量與類型3.3 程序控制結(jié)構(gòu)3.4 集合3.5 函數(shù)式編程3.6 本章小結(jié)3.1 Scala簡介 Scala語言是集面向?qū)ο缶幊趟枷肱c函數(shù)式編程思想于一身的通用編程語言,由Martin Odersky教授及其領(lǐng)導(dǎo)的瑞士洛桑聯(lián)邦高等理工學院程序

2、方法實驗室團隊于2004年對外發(fā)布。Scala的設(shè)計吸收借鑒了許多種編程語言的思想。Scala語言的名稱來自于“可伸展的語言”,從寫小腳本到建立大系統(tǒng)的編程任務(wù)均可勝任。3.1 Scala簡介 Scala運行于Java 虛擬機(Java Virtual Machine,JVM)上,并兼容現(xiàn)有的Java程序。Scala代碼可以調(diào)用Java方法,訪問Java成員變量,繼承Java類和實現(xiàn)Java接口。在面向?qū)ο蠓矫?,Scala是一門非常純粹的面向?qū)ο缶幊陶Z言,也就是說,在Scala中,每個值都是對象,每個操作都是方法調(diào)用。 3.1.1 Scala特點 Spark的設(shè)計目的之一就是使程序編寫更快更容

3、易,這也是Spark選擇Scala的原因所在。Scala的主要優(yōu)點包括:(1)Scala具備強大的并發(fā)性,支持函數(shù)式編程,可以更好地支持分布式系統(tǒng)。(2)Scala語法簡潔,能提供優(yōu)雅的API。(3)Scala能夠無縫集成Java語言,運行速度快,且能融合到Hadoop生態(tài)圈中。3.1.1 Scala特點 Scala的優(yōu)勢是提供了REPL(Read-Eval-Print Loop,交互式解釋器),因此,在Spark Shell中可進行交互式編程,即表達式計算完成就會輸出結(jié)果,而不必等到整個程序運行完畢,因此可即時查看中間結(jié)果,并對程序進行修改。這樣可以在較大程度上提升開發(fā)效率。3.1.2 Sc

4、ala運行方式 Scala代碼可以在Spark Shell中運行,其自帶Scala解釋器。當然,Scala代碼也可以在Scala Shell中直接運行。在實際開發(fā)過程中,為提高開發(fā)效率,一般會借助一些IDE如IDEA、Eclipse等進行Scala程序開發(fā)。3.1.2 Scala運行方式 由于本書只對Scala語言的常用語法知識進行講解,不涉及太過復(fù)雜的Scala程序,在Scala Shell里便可完成相關(guān)知識的學習。 本小節(jié)以輸出HelloWorld為例,介紹三種Scala代碼編譯執(zhí)行的方式。3.1.2 Scala運行方式 1. Scala解釋器中直接運行代碼 登錄Linux系統(tǒng),打開命令行

5、終端并輸入scala進入Scala解釋器。輸入代碼: 結(jié)果會直接顯示在代碼下方,輸出Hello,world!scala println(Hello, world!)Hello, world!3.1.2 Scala運行方式 2. Scala解釋器中運行多行代碼 在Scala解釋器中使用:paste命令,進入paste模式。將代碼編輯完后,按住ctrl+D即可退出paste模式,運行結(jié)果即可在下方顯示,如代碼 3-1所示。3.1.2 Scala運行方式 代碼3-1 另外,在Scala解釋器中輸入:quit可以退出Scala解釋器。3.1.2 Scala運行方式 3. 通過控制臺進行編譯及執(zhí)行sca

6、la文件 登錄Linux系統(tǒng),打開命令行終端,選擇文件創(chuàng)建路徑,在命令行終端輸入vim Demo.scala, 即可在創(chuàng)建路徑下自動創(chuàng)建Demo.scala文件。將代碼以應(yīng)用程序?qū)ο蟮姆绞綄懭雜cala文件,如代碼 3-2所示。3.1.2 Scala運行方式 代碼3-23.1.2 Scala運行方式 使用scalac命令編譯Demo.scala文件,并使用scala命令執(zhí)行: 執(zhí)行命令中一定要加入“-classpath .”,否則會出現(xiàn)“No such file or class on classpath: HelloWorld”。命令執(zhí)行后,會在屏幕上打印出“Hello, World!”。s

7、calac Demo.scala /編譯Scala文件命令scala -classpath . HelloWorld /執(zhí)行命令3.1.2 Scala運行方式 關(guān)于代碼 3-2及執(zhí)行命令,需要說明的幾點: 在代碼 3-2中,定義了程序的入口main()方法。關(guān)于main()方法的定義,Java和Scala是不同的,在Java中使用靜態(tài)方法(public static void main(String args)),而Scala中則必須使用對象方法,本例中,也就是HelloWorld對象中的main()方法。3.1.2 Scala運行方式 在代碼 3-2中對象的命名HelloWorld可以不必和

8、文件名稱一致,這里對象名稱是HelloWorld,而文件名稱是Demo.scala。這點和Java是不同的,按照Java的命名要求,這里的文件名稱就必須起名為HelloWorld.scala,但是,在Scala中沒有這個一致性要求。另外,執(zhí)行命令中的HelloWorld為對象名。3.1.2 Scala運行方式 Scala是區(qū)分大小寫的。例如小寫開頭的object和大寫開頭的Object是不同的。文件名Demo.scala和demo.scala也是兩個不同的文件。3.2.1 變量與類型 定義變量和數(shù)據(jù)類型是任何一門編程語言的入門基礎(chǔ)。本節(jié)將詳細介紹Scala中變量的定義與使用、命名規(guī)范、基本數(shù)據(jù)

9、類型及其使用以及Range操作等相關(guān)知識。3.2.1 變量的定義與使用 Scala中有三種類型的變量:不可變變量、可變變量和惰性變量。1.不可變變量 不可變變量指的是變量一旦被賦值,變量值在程序運行的過程中不會被改變,不可變變量使用關(guān)鍵字val進行定義,類似于Java中final關(guān)鍵字,在聲明時就必須被初始化,而且初始化以后不能再賦值。3.2.1 變量的定義與使用 使用關(guān)鍵字val定義不可變變量的示例如代碼 3-3所示。 第1行代碼是輸入的代碼,敲入回車后,Scala解釋器會解析輸入的代碼,然后返回執(zhí)行結(jié)果,第2行是Scala解釋器執(zhí)行后返回的結(jié)果,TestString變量的類型是String

10、類型,變量的值是Hello World! 。/聲明一個val變量,Scala會自動類型推斷scala val TestString=Hello World!TestString: String = Hello World!代碼3-33.2.1 變量的定義與使用 盡管在第1行代碼的聲明中,沒有給出TestString是String類型,但是,Scala具有“類型推斷”能力,可以自動推斷出變量的類型,如代碼 3-4所示。 代碼3-4/聲明一個val變量,明確指定變量的類型scala val TestString:String=Hello World!TestString: String = Hel

11、lo World!3.2.1 變量的定義與使用 String類型全稱是java.lang.String,也就是說,Scala的字符串是由Java的String類來實現(xiàn)的,因此,也可以使用java.lang.String來聲明,如代碼 3-5所示。 代碼3-5/String全稱是java.lang.String,Scala會默認導(dǎo)入java.lang包scala val TestString:java.lang.String=Hello World!TestString: String = Hello World! /打印變量 scala println(TestString)Hello Wor

12、ld!3.2.1 變量的定義與使用 Scala中可以不用java.lang.String,而只需要使用String聲明變量的原因是在每個應(yīng)用程序中,Scala都會自動添加一些引用,這就相當于在每個程序源文件的頂端都增加了一行代碼: /手動導(dǎo)入相應(yīng)的包 scala import java.lang._ import java.lang._3.2.1 變量的定義與使用 因為TestString是val變量,因此,一旦初始化以后,就不能再次賦值,所以,執(zhí)行再次賦值操作會報錯。示例如代碼 3-6所示。 代碼3-6/不能被重新賦值,因為它是val變量 scalaTestString=Hello Scal

13、a!:15: error: reassignment to val TestString=Hello Scala! 3.2.1 變量的定義與使用2.可變變量 可變變量指的是變量被賦值后,變量值可以隨著程序的運行而改變。可變變量使用關(guān)鍵字var進行定義,相當于Java中的變量,聲明的時候需要進行初始化,初始化以后還可以再次對其賦值。3.2.1 變量的定義與使用 如果一些變量,在初始化以后還要不斷修改它的值,則需要聲明為var變量。示例如代碼 3-7和代碼 3-8所示。把TestString聲明為var變量,并且在聲明的時候需要進行初始化。 代碼3-7/var聲明可變變量scala var Tes

14、tString=Hello Cruel World!TestString:String: = Hello Cruel World!3.2.1 變量的定義與使用 然后,可以再次對TestString進行賦值。 通過代碼 3-7和代碼 3-8可以看到,Scala中使用var關(guān)鍵字定義的變量在程序運行過程中值可以隨著程序的運行而發(fā)生改變。代碼3-8/對var變量重新賦值scala TestString=Hello Wonderful World!TestString:String: = Hello Wonderful World!3.2.1 變量的定義與使用 盡管var變量可以重新賦值,但是不能改變

15、它的類型,所以不能將一個變量重新賦值為與定義類型不兼容的數(shù)據(jù)。例如,定義一個類型為Int的變量,并為其賦一個String值,會導(dǎo)致編譯錯誤,如代碼 3-9所示。 3.2.1 變量的定義與使用 代碼3-9/定義一個類型為Int的變量xscalavar x=5x:Int =5 /重新賦一個String值,會導(dǎo)致編譯錯誤。scalax=Hello World:8:error:type mismatch; found : String(Hello World) required : Intx=Hello World 3.2.1 變量的定義與使用 如果定義一個類型為Double的var變量,可以再為其賦

16、一個Int類型的值,因為Int類型可以自動轉(zhuǎn)換為Double類型,如代碼 3-10所示。 代碼3-10/定義一個類型為Double的變量yscalavar y=1.5y:Double =1.5 /重新賦值一個Int數(shù)scalay=42y:Double =42.03.2.1 變量的定義與使用3.惰性變量 惰性變量指使用lazy關(guān)鍵字來修飾的變量,經(jīng)過lazy關(guān)鍵字修飾的變量只有在真正使用時才會被賦值。而且lazy關(guān)鍵字只能修飾val類型的變量,而不能修飾var類型的變量。3.2.1 變量的定義與使用 Scala中的惰性變量使用lazy關(guān)鍵字來修飾,用lazy關(guān)鍵字修飾過的變量只有在真正使用時才會

17、被賦值,示例如代碼 3-11所示。 代碼3-11/普通val變量定義scalaval TestString=Hello ScalaTestString: String = Hello Scala /經(jīng)過lazy關(guān)鍵字修飾的變量在定義時不被賦值scala lazy val TestString=Hello ScalaTestString:String = /在使用時,變量才會賦值scalaTestStringres0: String= Hello Scala3.2.1 變量的定義與使用 代碼lazy val TestString=Hello Scala定義了一個val類型的變量,該變量在定義時沒

18、有被賦值,所以返回結(jié)果為TestString:String =,只有在使用時才被賦值。與普通變量不同的是,普通變量在賦值后立即會得到賦值結(jié)果。 3.2.1 變量的定義與使用 lazy關(guān)鍵字不能用于var類型變量主要是為了避免程序運行過程中變量未使用便被重新賦值,如代碼 3-12所示。 代碼3-12/不能將lazy關(guān)鍵字用于var變量scalalazy var TestString2=Goodbye Scala:1:error:lazy not allowed here. Only vals can be lazy Lazy var TestString2=Goodbye Scala3.2.1

19、變量的定義與使用4.命名規(guī)范 Scala中的變量命名可以使用字母、數(shù)字和一些特殊的操作字符。因此可以使用標準算術(shù)運算符(例如*和+)和常量(例如和)取代比較長的命名,從而使代碼更有表述性。結(jié)合字母、數(shù)字和字符構(gòu)成Scala合法標識符的規(guī)則如下:3.2.1 變量的定義與使用一個字母后跟有0個或多個字母和數(shù)字,如a123、aa123等。一個字母后跟有0個或者多個字母和數(shù)字,接著是一個下劃線“_”,后面是一個或多個字母和數(shù)字或者是一個或多個操作符,如a_1、a_b、a1_*等。 3.2.1 變量的定義與使用一個或多個操作符,如+、*、-、/等。一個或者多個除反引號外的任意字符,這些字符被包含在一對反

20、引號中,如a.b是錯誤命名,而加上反引號的a.b是正確的。 3.2.1 變量的定義與使用Scala中有些保留字,不能用作標識符,但是反引號括起來除外,如return是保留字,標志為Do.return是非法的,但Do.return是合法的。保留字一般可以通過查詢保留字表得出,往往是常用的有特定含義的單詞,如case、else等。 3.2.1 變量的定義與使用 Scala中的保留字如表3-4所示:3.2.1 變量的定義與使用 在Scala解釋器中嘗試這些命名規(guī)則如代碼 3-13所示。 代碼3-13/特殊字符”是一個合法的Scala標識符scalaval =3.14159:Double = 3.14

21、159 /特殊字符”$”是一個合法的Scala標識符scala val $ =USD currency symbol$:String = USD currency symbol /”o_0 ”是一個合法的Scala標識符scala val o_0 =Hmmo_0:String =Hmm3.2.1 變量的定義與使用 續(xù)代碼3-13/值名”50cent”是不合法的,因為標識符不能以數(shù)字開頭。在這里,編譯器最初會把這個名字解析為一個數(shù)字,解析到字母”c”時會出錯scalaval 50cent=$0.50:1: error: Invalid literal numberval 50cent=$0.50

22、/值名”a.b”是不合法的,因為點號不是操作符字符scala val a.b=25:11: error: not found: value a val a.b=25 /加上反引號重寫就可以解決問題scala val a.b=4a.b: Int = 43.2.1 變量的定義與使用 按慣例,值和變量名應(yīng)當用小寫字母開頭,其余單詞的首字母大寫。這通常稱為camel case記法,盡管并不嚴格要求這樣做,但建議scala開發(fā)人員采用這種記法。3.2.2 基本數(shù)據(jù)類型和操作 本小節(jié)將對Scala的基本數(shù)據(jù)類型進行詳細的介紹,如:Char、Int、Float、Double和Boolean等;同時將介紹算術(shù)

23、運算操作、關(guān)系運算操作以及邏輯運算操作。3.2.2 基本數(shù)據(jù)類型和操作 1. 基本數(shù)據(jù)類型 Scala的數(shù)據(jù)類型包括:Byte、Char、Short、Int、Long、Float、Double和Boolean。和Java不同的是,除了這些數(shù)據(jù)類型首字母需要大寫外,在Scala中,這些類型都是“類”,并且都是scala包的成員,比如,Int的全名是scala.Int。對于字符串,Scala用java.lang.String類來表示字符串。3.2.2 基本數(shù)據(jù)類型和操作 Scala中數(shù)值數(shù)據(jù)類型如表 3-5所示。3.2.2 基本數(shù)據(jù)類型和操作 (1)Int類型 Int類型對應(yīng)的變量是整型變量,變量

24、對應(yīng)的是整型數(shù)據(jù)。Int類型變量的定義包括十六進制和十進制定義法,而八進制定義法從Scala 2.10版本開始已經(jīng)取消。3.2.2 基本數(shù)據(jù)類型和操作 代碼 3-14給出了整型變量的十六進制定義法和十進制定義法。代碼3-14/十六進制定義法scalaval x=0 x29x:Int =41 /十進制定義法scalaval y=41y:Int =413.2.2 基本數(shù)據(jù)類型和操作 (2)Float類型 Float類型表示的是浮點數(shù)。如果直接輸入一個浮點數(shù),Scala編譯器會自動進行類型推導(dǎo),并自動解釋成Double類型,所以需要在浮點數(shù)后加F或f才能定義Float類型的變量。Float類型變量定

25、義如代碼 3-15所示。3.2.2 基本數(shù)據(jù)類型和操作 Float類型變量定義如代碼 3-15所示。代碼3-15/要定義Float類型浮點數(shù),需要在浮點數(shù)后面加F或fscalaval floatNumber=3.14159FfloatNumber: Float=3.14159 /小寫的f也可以scalaval floatNumber=3.14159ffloatNumber: Float=3.141593.2.2 基本數(shù)據(jù)類型和操作 (3)Double類型 Double數(shù)據(jù)類型表示的是雙精度的浮點數(shù)。Double類型變量的定義如代碼 3-16所示。/Double類型定義,直接輸入浮點數(shù),編譯器會

26、將其自動推斷為Double類型scalaval doubleNumber=3.14159doubleNumber:Double=3.14159代碼3-163.2.2 基本數(shù)據(jù)類型和操作 雙精度浮點類型的變量還可以采用指數(shù)表示法,浮點數(shù)后加E或e均可,如代碼 3-17所示。代碼3-17/浮點數(shù)指數(shù)表示法,e也可以是E,0.314159e1與0.314159*10等同scalaval floatNumber=0.314159e1floatNumber: Double=3.141593.2.2 基本數(shù)據(jù)類型和操作 (4)Char類型 Char數(shù)據(jù)類型表示的是字符類型,用單引號 將字符包裹起來。Cha

27、r類型變量定義如代碼 3-18所示。/字符定義,用 將字符包裹scalavar charLiteral=AcharLiteral:Char=A代碼3-183.2.2 基本數(shù)據(jù)類型和操作 部分特殊字符如雙引號、換行符及反斜杠等的定義需要加轉(zhuǎn)義符“”或者使用對應(yīng)的Unicode編碼,代碼 3-19給出了雙引號字符的定義。代碼3-19/通過轉(zhuǎn)義符進行雙引號的定義scalavar x=x:Char = /通過使用Unicode編碼進行雙引號的定義scalavar y=u0022y:Char = 3.2.2 基本數(shù)據(jù)類型和操作 (5)String類型 String數(shù)據(jù)類型表示的是字符串類型,用雙引號 將

28、字符串包裹起來。String類型變量的定義如代碼 3-20所示。代碼3-20/字符串變量用雙引號包裹scalaval helloWorld=Hello WorldhelloWorld:String =Hello World3.2.2 基本數(shù)據(jù)類型和操作 如果字符串類型中有雙引號,則需要使用轉(zhuǎn)義符“”。示例如代碼 3-21所示。代碼3-21/要定義Hello World,可以加入轉(zhuǎn)義符scalaval helloWorld2=Hello WorldhelloWorld2:String =Hello World3.2.2 基本數(shù)據(jù)類型和操作 (6)Boolean類型 Boolean數(shù)據(jù)類型表示的是

29、布爾類型,包括true和false。Boolean類型變量的定義示例如代碼 3-22所示。代碼3-22/直接定義Boolean類型變量scalavar x=truex:Boolean = true /含邏輯表達式的Boolean類型變量scalavar y=23y:Boolean = false3.2.2 基本數(shù)據(jù)類型和操作 2.基本數(shù)據(jù)操作 Scala中基本數(shù)據(jù)類型的操作主要包括算術(shù)運算操作、關(guān)系運算操作和邏輯運算操作。本部分將分別就這三種運算操作進行介紹。3.2.2 基本數(shù)據(jù)類型和操作 (1)算術(shù)運算操作 在Scala中,可以使用加(+)、減(-) 、乘(*) 、除(/) 、取余(%)等操

30、作符,而且,這些操作符相當于方法。以加法為例,例如,5 + 3和(5).+(3)是等價的,即 a 方法 b 與 a.方法(b) 這二者是等價的。前者是后者的簡寫形式,這里的+是方法名,是Int類中的一個方法,如代碼 3-23所示。 3.2.2 基本數(shù)據(jù)類型和操作 代碼3-23/實際上調(diào)用了(5).+(3)scala val sum1 = 5+3 sum1: Int = 8 /可以發(fā)現(xiàn),寫成方法調(diào)用的形式,和上面得到相同的結(jié)果scala val sum2 = (5).+(3) sum2: Int = 8 3.2.2 基本數(shù)據(jù)類型和操作 在Scala中并沒有提供+和-操作符,當需要遞增或遞減時,可

31、以采用如代碼 3-24所示方式表達。 代碼3-24/定義整型變量iscala var i = 5i: Int = 5 /將i遞增scala i += 1 scala println(i)6 3.2.2 基本數(shù)據(jù)類型和操作 Scala語言還提供了用+、-符號來表示正負數(shù),并且這兩個符號可以直接在操作中使用,例如: /1 + -3 編譯器將-3解釋成一個負數(shù)scala var y=1 + -3y: Int = -23.2.2 基本數(shù)據(jù)類型和操作 (2)關(guān)系運算操作 Scala的關(guān)系運算操作包括大于()、小于(=)和小于等于(運算符scalavar res=32res: Boolean =true

32、/res= !(3 val bool=truebool :Boolean = true /邏輯與&,同時為true時才會為true,否則為falsescalabool & !boolres0: Boolean = false /邏輯或|,同時為false時才為false,否則為truescala!bool | boolres1: Boolean = true 3.2.2 基本數(shù)據(jù)類型和操作 續(xù)代碼3-26/邏輯或|,同時為false時才為falsescalabool | !boolres0: Boolean = true scalafalse | falseres1: Boolean = fa

33、lse3.2.3 Range操作 有時需要一個數(shù)字序列,從某個起點到某個終點。比如在執(zhí)行for循環(huán)時,i的值從1循環(huán)到5,這時就可以采用Range來實現(xiàn)。Range可以支持創(chuàng)建不同數(shù)據(jù)類型的數(shù)值序列,包括Int、Long、Float、Double、Char、BigInt和BigDecimal等。 3.2.3 Range操作 在創(chuàng)建Range時,需要給出區(qū)間的起點和終點以及步長(默認步長為1)。創(chuàng)建的Range可以包含區(qū)間終點(to),也可以不包含區(qū)間終點(until)。本小節(jié)將通過幾個示例來介紹Range的相關(guān)用法。 3.2.3 Range操作 1.創(chuàng)建一個從1到5的數(shù)值序列,包含區(qū)間終點5,

34、步長為1。 也可以使用另一種方式來實現(xiàn):2.創(chuàng)建一個從1到5的數(shù)值序列,不包含區(qū)間終點5,步長為1。scala 1 to 5res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5) scala 1.to(5)res1: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5)scala 1 until 5res2: scala.collection.immutable.Range = Range(1, 2, 3, 4)3.2.3 Ran

35、ge操作 3.創(chuàng)建一個從1到10的數(shù)值序列,包含區(qū)間終點10,步長為2。 /Int類型scala 1 to 10 by 2res3: scala.collection.immutable.Range = Range(1, 3, 5, 7, 9) /Long類型scala 1L to 10L by 2res4: scala.collection.immutable.NumericRangeLong = NumericRange(1, 3, 5, 7, 9) /BigInt類型scala BigInt(1) to BigInt(10) by 2res5: scala.collection.immu

36、table.NumericRangeBigInt = NumericRange(1, 3, 5, 7, 9) 代碼3-273.2.3 Range操作 4.創(chuàng)建一個從10到1的數(shù)值序列,包含區(qū)間終點1,步長為-2。5.創(chuàng)建一個Char類型的數(shù)值序列,從a到g,步長為3。 scala 10 to 1 by -2res6: scala.collection.immutable.Range = Range(10, 8, 6, 4, 2) scalaa to g by 3res10: scala.collection.immutable.NumericRangeChar = NumericRange(a

37、,d,g) 3.2.3 Range操作 6.創(chuàng)建一個浮點類型的數(shù)值序列,從0.5f到5.9f,步長為0.8f。 /Float類型scala 0.5f to 5.9f by 0.8fres7: scala.collection.immutable.NumericRangeFloat = NumericRange(0.5, 1.3, 2.1, 2.8999999, 3.6999998, 4.5, 5.3) /Double類型scala 0.5 to 5.9 by 0.8res8: scala.collection.immutable.NumericRangeDouble = NumericRang

38、e(0.5, 1.3, 2.1, 2.9000000000000004, 3.7, 4.5, 5.3) /BigDecimal類型scala BigDecimal(0.5) to BigDecimal(5.9) by 0.8res9: scala.collection.immutable.NumericRange.Inclusivescala.math.BigDecimal = NumericRange(0.5, 1.3, 2.1, 2.9, 3.7, 4.5, 5.3)代碼3-283.3 程序控制結(jié)構(gòu) 表達式為函數(shù)式編程提供了基礎(chǔ),利用表達式可以返回數(shù)據(jù)而不會修改現(xiàn)有的數(shù)據(jù),如變量。如果所有

39、代碼可以組織為一組有層次的表達式,包括一個或者多個返回值的表達式,使用不可變數(shù)據(jù)就比較自然。表達式的返回值會傳遞到其他表達式,或者存儲到值中。通過減少變量的使用,就可以減少函數(shù)和表達式的副作用。3.3.1 if條件表達式 if語句是許多編程語言中都會用到的條件控制結(jié)構(gòu)。在Scala中,執(zhí)行if語句時,首先檢查if條件是否為真,如果為真,就執(zhí)行對應(yīng)的語句塊,如果為假,就執(zhí)行下一個條件分支。3.3.1 if條件表達式 1. if語句 語法格式: if(條件判斷) /條件判斷為真時執(zhí)行 3.3.1 if條件表達式 示例如代碼3-29所示。 運行結(jié)果: This is if statement 代碼3

40、-293.3.1 if條件表達式2. if.else.語句 語法格式: if(條件判斷) /條件判斷為真時執(zhí)行 else /條件判斷為假時執(zhí)行 3.3.1 if條件表達式 示例如代碼3-30所示。 運行結(jié)果: This is else statement 代碼3-303.3.1 if條件表達式3. 多重if.else.的使用 語法格式: if(條件判斷 1) /條件判斷1為真時執(zhí)行 else if(條件判斷 2) /條件判斷2為真時執(zhí)行 else if(條件判斷3) /條件判斷3為真時執(zhí)行 else /條件判斷1、2、3均為假時執(zhí)行 3.3.1 if條件表達式 示例如代碼3-31所示。 運行結(jié)

41、果:Value of X is 30 代碼3-313.3.1 if條件表達式4. if語句的嵌套使用 語法格式: if(條件判斷 1) /條件判斷1為真時執(zhí)行 if(條件判斷2) /條件判斷2為真時執(zhí)行 3.3.1 if條件表達式 示例如代碼3-32所示。 運行結(jié)果:X = 30 and Y = 10 代碼3-323.3.2 循環(huán)表達式 本小節(jié)將介紹while循環(huán)、do.while循環(huán)以及各種形式的for循環(huán),for循環(huán)語句具有表達式的特性,在運行完成后可以有返回值,然而while循環(huán)雖然有返回值,但是返回值類型始終為Unit類型(相當于Java中void類型)。3.3.2 循環(huán)表達式 1.

42、while循環(huán) 語法格式: while(條件判斷) /條件判斷為真時執(zhí)行 3.3.2 循環(huán)表達式 示例如代碼3-33所示。 運行結(jié)果:here is 6 here is 3 here is 0 代碼3-333.3.2 循環(huán)表達式 2. do.while循環(huán) 語法格式: do /執(zhí)行循環(huán)體代碼 while(根據(jù)條件,判斷是否繼續(xù)執(zhí)行循環(huán)) 3.3.2 循環(huán)表達式 示例如代碼3-34所示。 運行結(jié)果:here is 6 here is 3 here is 0 代碼3-343.3.2 循環(huán)表達式3. for循環(huán) (1)基礎(chǔ)for循環(huán) Scala中沒有Java中的for(初始化變量;條件判斷;更新變量

43、)循環(huán),而有其獨特的for循環(huán)風格。Scala中的for循環(huán)語句格式: for (變量-表達式) /循環(huán)語句塊 其中,“變量-表達式”被稱為“生成器(generator)”。3.3.2 循環(huán)表達式 示例: i不需要提前進行變量聲明,可以在for語句括號中的表達式中直接使用。語句中,“for (i for (i for (i for(i-1 to 2;jfor (i - 1 to 5 if i%2=0; j - 1 to 3 if j!=i) println(i*j)3.3.2 循環(huán)表達式(3)多重for循環(huán) Scala中的多重for循環(huán),其語法格式: for(變量1-表達式 條件判斷) for

44、(變量2 for (i - 1 to 5 if i%2=0) yield i res0 : scala.collection.immutable.IndexedSeqInt = Vector(2, 4) 3.3.3 匹配表達式 Java中有switch-case語句,但是,只能按順序匹配簡單的數(shù)據(jù)類型和表達式。相對而言,Scala中的模式匹配的功能則要強大得多,可以應(yīng)用到switch語句、類型檢查以及“解構(gòu)”等多種場合。3.3.3 匹配表達式 1.簡單匹配 Scala的模式匹配最常用于match語句中。語法格式: match case = case. 3.3.3 匹配表達式 一個簡單的整型值的

45、匹配示例如代碼3-37所示。 代碼3-37運行結(jié)果: many 3.3.3 匹配表達式 另外,在模式匹配的case語句中,還可以使用變量,如代碼 3-38所示。當x=5時,值5會被傳遞給unexpected變量。 代碼3-38運行結(jié)果: 5 is Not Allowed 3.3.3 匹配表達式 同時,在模式匹配的case語句中可以使用不同的數(shù)據(jù)類型,如代碼 3-39所示。 代碼3-39運行結(jié)果:2manyOne3.3.3 匹配表達式 可以在模式匹配中添加一些必要的處理邏輯,如代碼 3-40所示。 代碼3-40運行結(jié)果:1 is odd.2 is even.3 is odd.4 is even.

46、3.3.3 匹配表達式 2. case類匹配 case類是一種特殊的類,其經(jīng)過優(yōu)化以被用于模式匹配。示例如代碼 3-41所示。 代碼3-41運行結(jié)果:Hi Alice!Hi Bob!Age: 32 year, name: Charlie?3.4 集合 Scala中集合分為兩種,一種是可變的集合,另一種是不可變的集合??勺兗峡梢员桓禄蛐薷?,添加、刪除、修改元素將作用于原集合。而不可變集合一旦被創(chuàng)建,便不能被改變,添加、刪除、更新操作返回的是新的集合,原有集合保持不變。本節(jié)將介紹Scala中常用的集合類型如數(shù)組、列表、集、映射、選項、迭代器及元組并給出對應(yīng)集合的常用函數(shù)的使用方法。3.4 數(shù)組

47、與列表Scala的Array是一個所有對象都共享相同類型的可變序列,盡管實例化之后無法改變Array的長度,它的元素值卻是可變的。因此,Array是可變的對象。 Scala的List是共享相同類型的不可變對象序列。列表類似于數(shù)組,它們所有元素的類型都相同,但是它們也有所不同:列表是不可變的,值一旦被定義了就不能改變。(ListBuffer,ArrayBuffer均可改變長度)元組tuple與列表一樣是不可變的,但與列表不同,元組可以包含不同類型的元素。3.4.1數(shù)組 數(shù)組為有序的相同類型的元素的集合,在Scala中數(shù)組是最常用、最重要的數(shù)據(jù)結(jié)構(gòu)。Scala中的數(shù)組分為定長數(shù)組和變長數(shù)組,定長數(shù)

48、組在定義時長度被確定,在運行時數(shù)組長度不會發(fā)生變化,而變長數(shù)組內(nèi)存空間長度會隨著程序運行的需要而動態(tài)擴容。本小節(jié)對定長數(shù)組和變長數(shù)組的使用、遍歷方式、多維數(shù)組等進行介紹。3.4.1數(shù)組1.定長數(shù)組(Array) 定長數(shù)組指的是數(shù)組長度在定義時被確定,數(shù)組占有的內(nèi)存空間在程序運行時不會被改變,定長數(shù)組的定義格式為(以String類型為例,定義一個長度為3的字符串數(shù)組): 或者 scalavar z:ArrayString = new ArrayString(3)scalavar z = new ArrayString(3)3.4.1數(shù)組(Array) 另外,可以通過Range生成數(shù)組,并對其進行

49、循環(huán)遍歷,具體示例如代碼 3-45所示。符串等非數(shù)值對象類型在數(shù)組定義時若沒有賦值,將會被初始化為null,而數(shù)值型數(shù)組在數(shù)組定義時未顯性賦值,則被初始化為0。可以給數(shù)組各元素自行賦值,比如: 或者也可以在一開始定義數(shù)組時便進行賦值,比如: 這種定義方式?jīng)]有直接通過顯式地new創(chuàng)建,而是調(diào)用了其apply方法進行數(shù)組創(chuàng)建操作。z(0) = Zara; z(1) = Nuha; z(2) = Ayanscalavar z = Array(Zara, Nuha, Ayan)3.4.1數(shù)組2.變長數(shù)組(ArrayBuffer) 變長數(shù)組在程序運行過程中,其數(shù)組長度可以隨程序運行的需要而增加。最常用的

50、變長數(shù)組為ArrayBuffer,它在包scala.collection.mutable中,在使用時需要顯式地引入,具體示例如代碼 3-42所示。 3.4.1數(shù)組運行結(jié)果:13AmyAyan 代碼3-423.4.1數(shù)組3. 數(shù)組遍歷 集合遍歷使用for循環(huán),數(shù)組遍歷也不例外。數(shù)組的遍歷有兩種方式,通過索引遍歷和直接數(shù)組遍歷。具體示例如代碼 3-43所示。 3.4.1數(shù)組運行結(jié)果:3.5Total is 11.7Max is 3.5代碼3-433.4.1數(shù)組 無論是定長數(shù)組還是變長數(shù)組,在遍歷時均可以生成新的數(shù)組。生成新數(shù)組時,原來數(shù)組內(nèi)容保持不變。具體示例如代碼 3-44所示

51、。3.4.1數(shù)組代碼3-44運行結(jié)果:數(shù)組代碼3-45運行結(jié)果:10 12 14 16 1810 11 12 13 14 15 16 17 18 19 另外,可以通過Range生成數(shù)組,并對其進行循環(huán)遍歷,具體示例如代碼 3-45所示。3.4.1數(shù)組4.多維數(shù)組 定義一個三行三列的整型二維數(shù)組: 與一維數(shù)組相同,也可以對二維數(shù)組進行賦值及循環(huán)遍歷,具體示例如代碼 3-46所示。 scalavar myMatrix = Array.ofDimInt(3,3)3.4.1數(shù)組代碼3-46運行結(jié)果:0 1 20 1 20 1 23.4.2 列表 同數(shù)組一樣,List也

52、是Scala語言中應(yīng)用十分廣泛的集合類型數(shù)據(jù)結(jié)構(gòu)。Scala列表與數(shù)組非常相似,列表中的所有元素都具有相同的類型,但是有一個重要的區(qū)別。列表是不可變的,這意味著列表的元素不能被賦值更改。 3.4.2 列表 1.創(chuàng)建列表 列表的創(chuàng)建如代碼3-47所示:/字符串類型Listscalaval fruit: ListString = List(apples, oranges, pears)fruit: ListString = List(apples, oranges, pears) /前一個語句與下面語句等同scalaval fruit: ListString = List.apply(apples

53、, oranges, pears)fruit: ListString = List(apples, oranges, pears)代碼3-473.4.2 列表 /數(shù)值類型Listscalaval nums: ListInt = List(1, 2, 3, 4)nums: ListInt = List(1, 2, 3, 4) /多重List,List的子元素為Listscalaval multiDList=List(List(1,2,3),List(4,5,6),List(7,8,9)multiDList=:ListListInt=List(List(1,2,3),List(4,5,6),Lis

54、t(7,8,9) /遍歷Listscalafor(ival fruit = apples : (oranges : (pears : Nil)fruit: ListString = List(apples, oranges, pears) /數(shù)值類型Listscalaval nums = 1 : (2 : (3 : (4 : Nil)nums: ListInt = List(1, 2, 3, 4) / 定義空列表scalaval empty = Nilempty: scala.collection.immutable.Nil.type = List()3.4.2 列表 續(xù)代碼3-48/多重Li

55、st,List的子元素為Listscala :paste/ Entering paste mode (ctrl-D to finish)val multiDList = (1 : (2 : (3 : Nil) : (4 : (5 : (6 : Nil) : (7 : (8 : (9 : Nil) : Nil/ Exiting paste mode, now interpreting.multiDList: ListListInt = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9)3.4.2 列表 可以使用list.fill()方法創(chuàng)建一個包含相

56、同元素的多個副本的列表。代碼3-49運行結(jié)果:fruit : List(apples, apples, apples)num : List(2, 2, 2, 2, 2, 2, 2, 2, 2, 2)3.4.2 列表 2. 基本操作 List的基本操作:head:該方法返回列表的第一個元素。tail:該方法返回包含除第一個元素之外的所有元素的列表。isEmpty:如果列表為空,則該方法返回true,否則為false。3.4.2 列表 具體示例如代碼 3-50所示: 代碼3-503.4.2 列表 運行結(jié)果:Head of fruit : applesTail of fruit : List(ora

57、nges, pears)Check if fruit is empty : falseCheck if nums is empty : true3.4.2 列表 3.連接列表 可以用:操作符或List.:()方法或List.concat()方法,添加兩個或更多的列表。具體示例如代碼 3-51所示。3.4.2 列表 代碼3-513.4.2 列表 運行結(jié)果:fruit1 : fruit2 : List(apples, oranges, pears, mangoes, banana)fruit1.:(fruit2) : List(mangoes, banana, apples, oranges, p

58、ears)List.concat(fruit1, fruit2) : List(apples, oranges, pears, mangoes, banana)3.4.3 集 集是不重復(fù)元素的集合。列表中的元素是按照插入的先后順序來組織的,但是,集中的元素并不會記錄元素的插入順序,而是以“哈?!狈椒▽υ氐闹颠M行組織,所以,其能快速地找到某個元素。 3.4.3 集 1. 創(chuàng)建集Set 集包括可變集和不可變集,缺省情況下創(chuàng)建的是不可變集,通常使用不可變集。用默認方式創(chuàng)建一個不可變集。/創(chuàng)建集mySetscala var mySet = Set(Hadoop,Spark)mySet: scala.

59、collection.immutable.SetString = Set(Hadoop, Spark) /向mySet中增加新的元素scala mySet += Scala scala println(mySet.contains(Scala)true代碼3-523.4.3 集 聲明的集為不可變集,如果使用val mySet += Scala 執(zhí)行時會報錯,所以需要聲明為var。如果要聲明一個可變集,則需要引入scala.collection.mutable.Set包,具體示例如下:3.4.3 集 /導(dǎo)入可變集包 scala import scala.collection.mutable.Se

60、timport scala.collection.mutable.Set /定義一個集合,這里使用的是mutablescala val myMutableSet = Set(Database,BigData)myMutableSet: scala.collection.mutable.SetString = Set(BigData, Database) /向集中添加一個元素。scala myMutableSet += Cloud Computingres0: myMutableSet.type = Set(BigData, Cloud Computing, Database) /輸出結(jié)果sca

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論