Scala進階之路-Scala的基本語法
作者:尹正傑
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
一.函數式編程初體驗Spark-Shell之WordCount
var arr=Array("hello","yinzhengjie","hello","world","yinzhengjie","big","data") //聲明一個數組 arr.map((_,1)).groupBy(_._1).mapValues(_.length).toList.sortBy(-_._2) //使用Spark進行單詞個數統計並進行降序
使用CMD窗口操作如下:
二.變量定義以及條件表達式
1>.數據類型介紹
答:Scala 和Java 相似,有7 種數值類型Byte、Char、Short、Int、Long、Float 和Double(無包裝類型)和Boolean、Unit 類型.注意:Unit 表示無值,和其他語言中void 等同。用作不返回任何結果的方法的結果類型。Unit只有一個實例值,寫成()。下圖展示了Scala中的整體類層級圖,其中Any
位於最頂端,Nothing
位於最底端。
2>.變量定義
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.basicGrammar 7 8 object DefiningVariable { 9 def main(args: Array[String]): Unit = { 10 /** 11 * 變量的定義可以用關鍵字var和val修飾 12 * var修飾的變量值可以更改 13 * val修飾的變量值不可用改變,相當於Java中final修飾的變量 14 * 定義變量格式如下 : 15 * 方式一 : var | val 變量名稱 : 類型 = 值 16 * 方式二 : var | val 變量名稱 = 值 17 * 18 */ 19 val name:String = "尹正傑" 20 var age:Int = 26 21 val blog = "http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/" 22 // 輸出我們上面定義的變量 23 println ("姓名 :" + name , "年齡 :" + age , "博客地址 :" + blog ) 24 25 /** 26 * Unit數據類型相當於Java中void關鍵字,但是在scala它的表示形式是一對括號,即"()"。 27 * 由於我println返回值為空,因此我定義了一個變量res它拿到的返回值必然為空。 28 */ 29 val res:Unit=println("yinzhengjie") 30 println(res) 31 /** 32 * 文字'f'插值器允許創建一個格式化的字符串,類似於C語言中的printf。注意,如果你沒有寫文字'f'插值器的話,格式化字符串會原樣輸出喲 33 * 在使用'f'插值器時,所有變量引用都應該是printf 樣式格式說明符,如%d,%i,%f 等。 34 */ 35 println (f"姓名 :$name%s 年齡 :$age, 博客地址 :$blog ") // 該行輸出有換行 36 /** 37 * 's'允許在處理字符串時直接使用變量。 38 * 在println 語句中將String 變量($name)附加到普通字符串中。 39 */ 40 println (s"Name=$name , Age=$age , Url=$blog ") 41 /** 42 * 字符串插入器還可以處理任意表達式。 43 * 使用's'字符串插入器處理具有任意表達式"${10 * 10}"的字符串"10 x 10"的以下代碼片段。任何表達式都可以嵌入到${}中。 44 */ 45 println (s"10 x 10 = ${10 * 10}") 46 47 /** 48 * 擴展小知識一: 49 * 多個變量聲明模式 50 */ 51 val (x,y,z) = (100,200,300) 52 println(s"x = ${x},y = ${y},z = ${z}") 53 54 /** 55 * 擴展小知識二 56 * 抽取前兩個元素依次賦值,目的只是關心a,b兩個值,這樣我們就可以直接輸出a和b的值 57 */ 58 val Array(a,b,_*) = Array("A","B","C","D") 59 println(s"a = ${a},b = ${b}") 60 61 62 } 63 } 64 65 66 67 /* 68 以上代碼輸出結果如下 : 69 (姓名 :尹正傑,年齡 :26,博客地址 :http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/) 70 yinzhengjie 71 () 72 姓名 :尹正傑 年齡 :26, 博客地址 :http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 73 Name=尹正傑 , Age=26 , Url=http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 74 10 x 10 = 100 75 x = 100,y = 200,z = 300 76 a = A,b = B 77 */
3>.條件表達式
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.variable 7 8 object ConditionalExpression { 9 def main(args: Array[String]): Unit = { 10 /** 11 * if 語句的使用 12 */ 13 val Name = "尹正傑" 14 if (Name == "尹正傑"){ 15 println("歡迎使用Scala!") 16 } 17 /** 18 * if...else 語句的使用 19 */ 20 val sex = "boy" 21 val res = if (sex == "boy") "小哥哥" else "小姐姐" //這個和Python中的三元表達式很像喲! 22 println(res) 23 24 /** 25 * if...else if ...else多分支語句 26 */ 27 val age:Int = 18 28 var Title = if (age > 38){ //注意:我們在定義Title變量是並沒有指定數據類型,編譯器會自動推測出返回值類型,如果上面都沒有返回默認就是Unit喲! 29 "大叔" 30 }else if (age > 20){ 31 "小哥哥" 32 }else{ 33 "小鮮肉" 34 } 35 println(s"${Title}") 36 } 37 } 38 39 40 41 /* 42 以上代碼輸出結果如下 : 43 歡迎使用Scala! 44 小哥哥 45 小鮮肉 46 */
三.循環語句for及yield關鍵字
1>.遍歷數組的幾種方式
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.variable 7 8 object CircularStatement { 9 def main(args: Array[String]): Unit = { 10 //定義一個數組 11 val arr = Array(1,2,3,4,5) 12 //遍歷數組的中的所有元素 13 for (item <- arr){ 14 print(item + " ") 15 } 16 println("\n=======我是分割線==========") 17 //定義一個數組,用面的每一個元素代表arr數組中的角標,從而達到訪問arr每一個元素的目的 18 val index = Array[Int](0,1,2,3,4) 19 for (item <- index){ 20 print(arr(item) + "|") 21 } 22 println("\n=======我是分割線==========") 23 //以角標的方式會訪問,注意“0 to 4”,會生成一個“(0,1,2,3,4)”的數組 24 for (item <- 0 to 4){ 25 print(arr(item) + " ") 26 } 27 println("\n=======我是分割線==========") 28 //以角標的方式會訪問,注意“0 until arr.length”,也會生成一個“(0,1,2,3,4)”的數組,因為arr.length的值為5 29 for (item <- 0 until arr.length){ 30 print(arr(item) + "|") 31 } 32 println("\n=======我是分割線==========") 33 //取出數組中的偶數元素 34 for (item <- arr){ 35 if (item % 2 == 0){ 36 print(item + " ") 37 } 38 } 39 println("\n=======我是分割線==========") 40 //當然,上面的循環表達式也可以簡寫,如下: 41 for (item <- arr if item % 2 == 0){ 42 print(item + " ") 43 } 44 } 45 } 46 47 48 49 50 51 /* 52 以上代碼執行結果如下 : 53 1 2 3 4 5 54 =======我是分割線========== 55 1|2|3|4|5| 56 =======我是分割線========== 57 1 2 3 4 5 58 =======我是分割線========== 59 1|2|3|4|5| 60 =======我是分割線========== 61 2 4 62 =======我是分割線========== 63 2 4 64 */
2>.循環的嵌套方式
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.variable 7 8 object CircularStatement { 9 def main(args: Array[String]): Unit = { 10 for (i <-1 to 3){ 11 for (j <- 1 to 3){ 12 if (i != j){ 13 print(10 * i + j + " ") 14 } 15 } 16 } 17 println("\n=======我是分割線==========") 18 //上面的for循環嵌套是很繁瑣的,我們可以用一行搞定! 19 for(i <- 1 to 3;j <-1 to 3 if i != j){ 20 print(10 * i + j + " ") 21 } 22 } 23 } 24 25 26 27 28 29 /* 30 以上代碼執行結果如下 : 31 12 13 21 23 31 32 32 =======我是分割線========== 33 12 13 21 23 31 32 34 */
3>.yield關鍵字
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.variable 7 8 object CircularStatement { 9 def main(args: Array[String]): Unit = { 10 11 val arr = Array(1,2,3,4,5) 12 13 //yield關鍵字和Python很類似,它可以多次返回值,比如我們判斷arr數組中存在的偶數值 14 var res = for(item <- arr if item % 2 == 0) yield item 15 16 //遍歷我們得到的數組 17 for(item <- 0 until res.length){ 18 print(res(item) + " ") 19 } 20 21 } 22 } 23 24 25 26 27 28 /* 29 以上代碼執行結果如下 : 30 2 4 31 */
4>.小試牛刀-打印九九乘法表
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.basicGrammar 7 8 object MultiplicationTable { 9 def main(args: Array[String]): Unit = { 10 for_while_99(9) 11 println("=======我是分割線==========") 12 while_while_99(10) 13 println("=======我是分割線==========") 14 for_for_99(9) 15 println("=======我是分割線==========") 16 senior_for(9) 17 } 18 19 /** 20 * 使用高級for循環打印99乘法表,當然是在傳遞的參數為9的情況下 21 */ 22 def senior_for(arg:Int):Unit={ 23 for(i<-1 to arg;j<-1 to i ){ 24 print(s"${i} x ${j} = ${i * j}\t") 25 if (j == i) { 26 println() 27 } 28 } 29 } 30 31 /** 32 * 使用for循環嵌套打印99乘法表,我們需要傳入一個參數,可以實現任意乘法表 33 */ 34 def for_for_99(arg:Int):Unit={ 35 for(i <- 1 to arg){ 36 for (j <- 1 to i){ 37 print(s"${i} x ${j} = ${i * j}\t") 38 if (j == i) { 39 println() 40 } 41 } 42 } 43 } 44 /** 45 * 使用while循環嵌套打印99乘法表,我們需要傳入一個參數,可以實現任意乘法表 46 */ 47 def while_while_99(arg:Int): Unit ={ 48 var i = 1 49 while (i < arg){ 50 var j = 1 51 while (j <= i){ 52 printf("%d x %d = %d\t",j,i,(j*i)) 53 if (j == i){ 54 println() 55 } 56 j+=1 57 } 58 i+=1 59 } 60 } 61 /** 62 * 使用while和for循環打印99乘法表,我們需要傳入一個參數,可以實現任意乘法表 63 */ 64 def for_while_99(arg:Int):Unit = { 65 var i: Int = 1 66 for (i <- 1 to arg) { 67 var j = 1 68 while (j <= i) { 69 print(s"${i} x ${j} = ${i * j}\t") 70 if (j == i) { 71 println() 72 } 73 j += 1 74 } 75 } 76 } 77 } 78 79 80 /* 81 以上代碼執行結果如下 : 82 1 x 1 = 1 83 2 x 1 = 2 2 x 2 = 4 84 3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 85 4 x 1 = 4 4 x 2 = 8 4 x 3 = 12 4 x 4 = 16 86 5 x 1 = 5 5 x 2 = 10 5 x 3 = 15 5 x 4 = 20 5 x 5 = 25 87 6 x 1 = 6 6 x 2 = 12 6 x 3 = 18 6 x 4 = 24 6 x 5 = 30 6 x 6 = 36 88 7 x 1 = 7 7 x 2 = 14 7 x 3 = 21 7 x 4 = 28 7 x 5 = 35 7 x 6 = 42 7 x 7 = 49 89 8 x 1 = 8 8 x 2 = 16 8 x 3 = 24 8 x 4 = 32 8 x 5 = 40 8 x 6 = 48 8 x 7 = 56 8 x 8 = 64 90 9 x 1 = 9 9 x 2 = 18 9 x 3 = 27 9 x 4 = 36 9 x 5 = 45 9 x 6 = 54 9 x 7 = 63 9 x 8 = 72 9 x 9 = 81 91 =======我是分割線========== 92 1 x 1 = 1 93 1 x 2 = 2 2 x 2 = 4 94 1 x 3 = 3 2 x 3 = 6 3 x 3 = 9 95 1 x 4 = 4 2 x 4 = 8 3 x 4 = 12 4 x 4 = 16 96 1 x 5 = 5 2 x 5 = 10 3 x 5 = 15 4 x 5 = 20 5 x 5 = 25 97 1 x 6 = 6 2 x 6 = 12 3 x 6 = 18 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36 98 1 x 7 = 7 2 x 7 = 14 3 x 7 = 21 4 x 7 = 28 5 x 7 = 35 6 x 7 = 42 7 x 7 = 49 99 1 x 8 = 8 2 x 8 = 16 3 x 8 = 24 4 x 8 = 32 5 x 8 = 40 6 x 8 = 48 7 x 8 = 56 8 x 8 = 64 100 1 x 9 = 9 2 x 9 = 18 3 x 9 = 27 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81 101 =======我是分割線========== 102 1 x 1 = 1 103 2 x 1 = 2 2 x 2 = 4 104 3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 105 4 x 1 = 4 4 x 2 = 8 4 x 3 = 12 4 x 4 = 16 106 5 x 1 = 5 5 x 2 = 10 5 x 3 = 15 5 x 4 = 20 5 x 5 = 25 107 6 x 1 = 6 6 x 2 = 12 6 x 3 = 18 6 x 4 = 24 6 x 5 = 30 6 x 6 = 36 108 7 x 1 = 7 7 x 2 = 14 7 x 3 = 21 7 x 4 = 28 7 x 5 = 35 7 x 6 = 42 7 x 7 = 49 109 8 x 1 = 8 8 x 2 = 16 8 x 3 = 24 8 x 4 = 32 8 x 5 = 40 8 x 6 = 48 8 x 7 = 56 8 x 8 = 64 110 9 x 1 = 9 9 x 2 = 18 9 x 3 = 27 9 x 4 = 36 9 x 5 = 45 9 x 6 = 54 9 x 7 = 63 9 x 8 = 72 9 x 9 = 81 111 =======我是分割線========== 112 1 x 1 = 1 113 2 x 1 = 2 2 x 2 = 4 114 3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 115 4 x 1 = 4 4 x 2 = 8 4 x 3 = 12 4 x 4 = 16 116 5 x 1 = 5 5 x 2 = 10 5 x 3 = 15 5 x 4 = 20 5 x 5 = 25 117 6 x 1 = 6 6 x 2 = 12 6 x 3 = 18 6 x 4 = 24 6 x 5 = 30 6 x 6 = 36 118 7 x 1 = 7 7 x 2 = 14 7 x 3 = 21 7 x 4 = 28 7 x 5 = 35 7 x 6 = 42 7 x 7 = 49 119 8 x 1 = 8 8 x 2 = 16 8 x 3 = 24 8 x 4 = 32 8 x 5 = 40 8 x 6 = 48 8 x 7 = 56 8 x 8 = 64 120 9 x 1 = 9 9 x 2 = 18 9 x 3 = 27 9 x 4 = 36 9 x 5 = 45 9 x 6 = 54 9 x 7 = 63 9 x 8 = 72 9 x 9 = 81 121 */
四.運算符重載成方法
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.variable 7 8 object OperatorReloadingMethod { 9 def main(args: Array[String]): Unit = { 10 var res1 = 1 + 2 11 println(res1) 12 //上面的運算符“+”其實是運算符重載成方法,即".+" 13 var res2 = 1.+(2) 14 println(res2) 15 16 val res3 = 1 to 10 17 println(res3) 18 //上面的運算符“to”其實也是運算符重載成方法,即".to" 19 val res4 = 1.to(10) 20 println(res4) 21 22 } 23 } 24 25 /* 26 以上代碼輸出結果如下 : 27 3 28 3 29 Range 1 to 10 30 Range 1 to 10 31 */
五.Scala中定義方法和函數簡介
1>.有參函數和無參函數以及方法轉換成函數案例
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object Method { 9 10 /** 11 * 定義有參函數 : 12 * 定義個 sum 方法(用關鍵字def來標識方法), 該方法有 3 個參數(即a,b和c), 參數類型為整型, 方法的返回值為整型, 13 */ 14 def sum(a:Int, b: Int,c:Int): Int = { 15 //方法體是將形參列表的三個參數進行相加操作,相加的結果就是返回值的整形 16 a + b + c 17 } 18 19 /** 20 * 定義無參函數 : 21 * 改方法沒有任何參數, 也沒有返回值。注意:如果方法沒有括號"()" 調用時不能加"()" 22 */ 23 def sayHello() ={ 24 println("I'm Yinzhengjie!") 25 } 26 27 def main(args: Array[String]): Unit = { 28 //調用有參函數 29 var res = sum(100,200,300) 30 println(res) 31 32 //調用無參函數,調用時可以省略括號"()", 也可以不省略。如果方法沒有括號"()",調用時不能加"()" 33 sayHello() 34 35 //方法可轉換為函數,格式很簡單,只需要在方法名后面加個空格和下划線即可。 36 var f1 = sum _ 37 //調用我們將方法轉換過來的函數 38 var res1 = f1(1,2,3) 39 println(res1) 40 } 41 } 42 43 /** 44 * 以上代碼執行結果如下 : 45 * 600 46 * I'm Yinzhengjie! 47 * 6 48 */
2>.匿名函數的兩種定義和調用方式
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.function 7 8 object Method { 9 10 /** 11 * 函數定義方式一: 12 * f1 : 13 * 其中f1是對匿名函數簽名的一個引用,我們可以通過f1去調用這個函數, 14 * (x : Int) : 15 * 其中x是變量的名稱,而Int是變量的類型 16 * => : 17 * 表示的是函數標志 18 * x * 2 : 19 * 表示的具體的函數體,即也是最終的返回值喲 20 */ 21 val f1 = (x:Int) => x * 2 22 23 24 /** 25 * 函數定義方式而: 26 * f2 : 27 * 其中f2是對匿名函數簽名的一個引用,我們可以通過f2去調用這個函數, 28 * (Int) : 29 * Int定義的是函數的參數類型,我這個定義了一個Int類型的參數,如果有多個用逗號分隔即可 30 * => : 31 * 表示的是函數標志 32 * Int : 33 * 表示的是返回值類型為Int 34 * (x) : 35 * 注意,這里的x實際上是形參,這個參數的類型就是前面我們定義的Int類型 36 * x * 2 : 37 * 表示的具體的函數體,即也是最終的返回值喲 38 */ 39 val f2 :(Int) => Int =(x) => x * 2 40 41 /** 42 * 下面為沒有任何參數的匿名函數, 函數的返回值為String類型. 43 * 44 */ 45 val f3:() => String = () => "尹正傑" 46 47 def main(args: Array[String]): Unit = { 48 //調用匿名函數f1 49 var res1 = f1(10) 50 println(res1) 51 52 //調用匿名函數f2 53 var res2 = f1(20) 54 println(res2) 55 56 //調用參數為空的匿名函數f3 57 val Name = f3(); 58 println(Name) 59 60 } 61 } 62 63 /** 64 * 以上代碼執行結果如下 : 65 * 20 66 * 40 67 * 尹正傑 68 */
想要了解更多關於函數知識點筆記請參考:https://www.cnblogs.com/yinzhengjie/p/9352798.html。