Scala进阶之路-Scala的基本语法

            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。

原文地址:https://www.cnblogs.com/yinzhengjie/p/9346524.html