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(" =======我是分割线==========") 17 //定义一个数组,用面的每一个元素代表arr数组中的角标,从而达到访问arr每一个元素的目的 18 val index = Array[Int](0,1,2,3,4) 19 for (item <- index){ 20 print(arr(item) + "|") 21 } 22 println(" =======我是分割线==========") 23 //以角标的方式会访问,注意“0 to 4”,会生成一个“(0,1,2,3,4)”的数组 24 for (item <- 0 to 4){ 25 print(arr(item) + " ") 26 } 27 println(" =======我是分割线==========") 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(" =======我是分割线==========") 33 //取出数组中的偶数元素 34 for (item <- arr){ 35 if (item % 2 == 0){ 36 print(item + " ") 37 } 38 } 39 println(" =======我是分割线==========") 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(" =======我是分割线==========") 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} ") 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} ") 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 ",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} ") 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。