Scala进阶之路-Scala的基本语法
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.函数式编程初体验Spark-Shell之WordCount
var arr=Array("hello","yinzhengjie","hello","world","yinzhengjie","big","data") //声明一个数组 arr.map((_,)).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>.变量定义
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.basicGrammar object DefiningVariable {
def main(args: Array[String]): Unit = {
/**
* 变量的定义可以用关键字var和val修饰
* var修饰的变量值可以更改
* val修饰的变量值不可用改变,相当于Java中final修饰的变量
* 定义变量格式如下 :
* 方式一 : var | val 变量名称 : 类型 = 值
* 方式二 : var | val 变量名称 = 值
*
*/
val name:String = "尹正杰"
var age:Int = 26
val blog = "http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/"
// 输出我们上面定义的变量
println ("姓名 :" + name , "年龄 :" + age , "博客地址 :" + blog ) /**
* Unit数据类型相当于Java中void关键字,但是在scala它的表示形式是一对括号,即"()"。
* 由于我println返回值为空,因此我定义了一个变量res它拿到的返回值必然为空。
*/
val res:Unit=println("yinzhengjie")
println(res)
/**
* 文字'f'插值器允许创建一个格式化的字符串,类似于C语言中的printf。注意,如果你没有写文字'f'插值器的话,格式化字符串会原样输出哟
* 在使用'f'插值器时,所有变量引用都应该是printf 样式格式说明符,如%d,%i,%f 等。
*/
println (f"姓名 :$name%s 年龄 :$age, 博客地址 :$blog ") // 该行输出有换行
/**
* 's'允许在处理字符串时直接使用变量。
* 在println 语句中将String 变量($name)附加到普通字符串中。
*/
println (s"Name=$name , Age=$age , Url=$blog ")
/**
* 字符串插入器还可以处理任意表达式。
* 使用's'字符串插入器处理具有任意表达式"${10 * 10}"的字符串"10 x 10"的以下代码片段。任何表达式都可以嵌入到${}中。
*/
println (s"10 x 10 = ${10 * 10}") /**
* 扩展小知识一:
* 多个变量声明模式
*/
val (x,y,z) = (100,200,300)
println(s"x = ${x},y = ${y},z = ${z}") /**
* 扩展小知识二
* 抽取前两个元素依次赋值,目的只是关心a,b两个值,这样我们就可以直接输出a和b的值
*/
val Array(a,b,_*) = Array("A","B","C","D")
println(s"a = ${a},b = ${b}") }
} /*
以上代码输出结果如下 :
(姓名 :尹正杰,年龄 :26,博客地址 :http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/)
yinzhengjie
()
姓名 :尹正杰 年龄 :26, 博客地址 :http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
Name=尹正杰 , Age=26 , Url=http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
10 x 10 = 100
x = 100,y = 200,z = 300
a = A,b = B
*/
3>.条件表达式
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.variable object ConditionalExpression {
def main(args: Array[String]): Unit = {
/**
* if 语句的使用
*/
val Name = "尹正杰"
if (Name == "尹正杰"){
println("欢迎使用Scala!")
}
/**
* if...else 语句的使用
*/
val sex = "boy"
val res = if (sex == "boy") "小哥哥" else "小姐姐" //这个和Python中的三元表达式很像哟!
println(res) /**
* if...else if ...else多分支语句
*/
val age:Int = 18
var Title = if (age > 38){ //注意:我们在定义Title变量是并没有指定数据类型,编译器会自动推测出返回值类型,如果上面都没有返回默认就是Unit哟!
"大叔"
}else if (age > 20){
"小哥哥"
}else{
"小鲜肉"
}
println(s"${Title}")
}
} /*
以上代码输出结果如下 :
欢迎使用Scala!
小哥哥
小鲜肉
*/
三.循环语句for及yield关键字
1>.遍历数组的几种方式
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.variable object CircularStatement {
def main(args: Array[String]): Unit = {
//定义一个数组
val arr = Array(1,2,3,4,5)
//遍历数组的中的所有元素
for (item <- arr){
print(item + " ")
}
println("\n=======我是分割线==========")
//定义一个数组,用面的每一个元素代表arr数组中的角标,从而达到访问arr每一个元素的目的
val index = Array[Int](0,1,2,3,4)
for (item <- index){
print(arr(item) + "|")
}
println("\n=======我是分割线==========")
//以角标的方式会访问,注意“0 to 4”,会生成一个“(0,1,2,3,4)”的数组
for (item <- 0 to 4){
print(arr(item) + " ")
}
println("\n=======我是分割线==========")
//以角标的方式会访问,注意“0 until arr.length”,也会生成一个“(0,1,2,3,4)”的数组,因为arr.length的值为5
for (item <- 0 until arr.length){
print(arr(item) + "|")
}
println("\n=======我是分割线==========")
//取出数组中的偶数元素
for (item <- arr){
if (item % 2 == 0){
print(item + " ")
}
}
println("\n=======我是分割线==========")
//当然,上面的循环表达式也可以简写,如下:
for (item <- arr if item % 2 == 0){
print(item + " ")
}
}
} /*
以上代码执行结果如下 :
1 2 3 4 5
=======我是分割线==========
1|2|3|4|5|
=======我是分割线==========
1 2 3 4 5
=======我是分割线==========
1|2|3|4|5|
=======我是分割线==========
2 4
=======我是分割线==========
2 4
*/
2>.循环的嵌套方式
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.variable object CircularStatement {
def main(args: Array[String]): Unit = {
for (i <-1 to 3){
for (j <- 1 to 3){
if (i != j){
print(10 * i + j + " ")
}
}
}
println("\n=======我是分割线==========")
//上面的for循环嵌套是很繁琐的,我们可以用一行搞定!
for(i <- 1 to 3;j <-1 to 3 if i != j){
print(10 * i + j + " ")
}
}
} /*
以上代码执行结果如下 :
12 13 21 23 31 32
=======我是分割线==========
12 13 21 23 31 32
*/
3>.yield关键字
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.variable object CircularStatement {
def main(args: Array[String]): Unit = { val arr = Array(1,2,3,4,5) //yield关键字和Python很类似,它可以多次返回值,比如我们判断arr数组中存在的偶数值
var res = for(item <- arr if item % 2 == 0) yield item //遍历我们得到的数组
for(item <- 0 until res.length){
print(res(item) + " ")
} }
} /*
以上代码执行结果如下 :
2 4
*/
4>.小试牛刀-打印九九乘法表
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.basicGrammar object MultiplicationTable {
def main(args: Array[String]): Unit = {
for_while_99(9)
println("=======我是分割线==========")
while_while_99(10)
println("=======我是分割线==========")
for_for_99(9)
println("=======我是分割线==========")
senior_for(9)
} /**
* 使用高级for循环打印99乘法表,当然是在传递的参数为9的情况下
*/
def senior_for(arg:Int):Unit={
for(i<-1 to arg;j<-1 to i ){
print(s"${i} x ${j} = ${i * j}\t")
if (j == i) {
println()
}
}
} /**
* 使用for循环嵌套打印99乘法表,我们需要传入一个参数,可以实现任意乘法表
*/
def for_for_99(arg:Int):Unit={
for(i <- 1 to arg){
for (j <- 1 to i){
print(s"${i} x ${j} = ${i * j}\t")
if (j == i) {
println()
}
}
}
}
/**
* 使用while循环嵌套打印99乘法表,我们需要传入一个参数,可以实现任意乘法表
*/
def while_while_99(arg:Int): Unit ={
var i = 1
while (i < arg){
var j = 1
while (j <= i){
printf("%d x %d = %d\t",j,i,(j*i))
if (j == i){
println()
}
j+=1
}
i+=1
}
}
/**
* 使用while和for循环打印99乘法表,我们需要传入一个参数,可以实现任意乘法表
*/
def for_while_99(arg:Int):Unit = {
var i: Int = 1
for (i <- 1 to arg) {
var j = 1
while (j <= i) {
print(s"${i} x ${j} = ${i * j}\t")
if (j == i) {
println()
}
j += 1
}
}
}
} /*
以上代码执行结果如下 :
1 x 1 = 1
2 x 1 = 2 2 x 2 = 4
3 x 1 = 3 3 x 2 = 6 3 x 3 = 9
4 x 1 = 4 4 x 2 = 8 4 x 3 = 12 4 x 4 = 16
5 x 1 = 5 5 x 2 = 10 5 x 3 = 15 5 x 4 = 20 5 x 5 = 25
6 x 1 = 6 6 x 2 = 12 6 x 3 = 18 6 x 4 = 24 6 x 5 = 30 6 x 6 = 36
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
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
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
=======我是分割线==========
1 x 1 = 1
1 x 2 = 2 2 x 2 = 4
1 x 3 = 3 2 x 3 = 6 3 x 3 = 9
1 x 4 = 4 2 x 4 = 8 3 x 4 = 12 4 x 4 = 16
1 x 5 = 5 2 x 5 = 10 3 x 5 = 15 4 x 5 = 20 5 x 5 = 25
1 x 6 = 6 2 x 6 = 12 3 x 6 = 18 4 x 6 = 24 5 x 6 = 30 6 x 6 = 36
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
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
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
=======我是分割线==========
1 x 1 = 1
2 x 1 = 2 2 x 2 = 4
3 x 1 = 3 3 x 2 = 6 3 x 3 = 9
4 x 1 = 4 4 x 2 = 8 4 x 3 = 12 4 x 4 = 16
5 x 1 = 5 5 x 2 = 10 5 x 3 = 15 5 x 4 = 20 5 x 5 = 25
6 x 1 = 6 6 x 2 = 12 6 x 3 = 18 6 x 4 = 24 6 x 5 = 30 6 x 6 = 36
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
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
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
=======我是分割线==========
1 x 1 = 1
2 x 1 = 2 2 x 2 = 4
3 x 1 = 3 3 x 2 = 6 3 x 3 = 9
4 x 1 = 4 4 x 2 = 8 4 x 3 = 12 4 x 4 = 16
5 x 1 = 5 5 x 2 = 10 5 x 3 = 15 5 x 4 = 20 5 x 5 = 25
6 x 1 = 6 6 x 2 = 12 6 x 3 = 18 6 x 4 = 24 6 x 5 = 30 6 x 6 = 36
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
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
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
*/
四.运算符重载成方法
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.variable object OperatorReloadingMethod {
def main(args: Array[String]): Unit = {
var res1 = 1 + 2
println(res1)
//上面的运算符“+”其实是运算符重载成方法,即".+"
var res2 = 1.+(2)
println(res2) val res3 = 1 to 10
println(res3)
//上面的运算符“to”其实也是运算符重载成方法,即".to"
val res4 = 1.to(10)
println(res4) }
} /*
以上代码输出结果如下 :
3
3
Range 1 to 10
Range 1 to 10
*/
五.Scala中定义方法和函数简介
1>.有参函数和无参函数以及方法转换成函数案例
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.function object Method { /**
* 定义有参函数 :
* 定义个 sum 方法(用关键字def来标识方法), 该方法有 3 个参数(即a,b和c), 参数类型为整型, 方法的返回值为整型,
*/
def sum(a:Int, b: Int,c:Int): Int = {
//方法体是将形参列表的三个参数进行相加操作,相加的结果就是返回值的整形
a + b + c
} /**
* 定义无参函数 :
* 改方法没有任何参数, 也没有返回值。注意:如果方法没有括号"()" 调用时不能加"()"
*/
def sayHello() ={
println("I'm Yinzhengjie!")
} def main(args: Array[String]): Unit = {
//调用有参函数
var res = sum(100,200,300)
println(res) //调用无参函数,调用时可以省略括号"()", 也可以不省略。如果方法没有括号"()",调用时不能加"()"
sayHello() //方法可转换为函数,格式很简单,只需要在方法名后面加个空格和下划线即可。
var f1 = sum _
//调用我们将方法转换过来的函数
var res1 = f1(1,2,3)
println(res1)
}
} /**
* 以上代码执行结果如下 :
* 600
* I'm Yinzhengjie!
* 6
*/
2>.匿名函数的两种定义和调用方式
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.function object Method { /**
* 函数定义方式一:
* f1 :
* 其中f1是对匿名函数签名的一个引用,我们可以通过f1去调用这个函数,
* (x : Int) :
* 其中x是变量的名称,而Int是变量的类型
* => :
* 表示的是函数标志
* x * 2 :
* 表示的具体的函数体,即也是最终的返回值哟
*/
val f1 = (x:Int) => x * 2 /**
* 函数定义方式而:
* f2 :
* 其中f2是对匿名函数签名的一个引用,我们可以通过f2去调用这个函数,
* (Int) :
* Int定义的是函数的参数类型,我这个定义了一个Int类型的参数,如果有多个用逗号分隔即可
* => :
* 表示的是函数标志
* Int :
* 表示的是返回值类型为Int
* (x) :
* 注意,这里的x实际上是形参,这个参数的类型就是前面我们定义的Int类型
* x * 2 :
* 表示的具体的函数体,即也是最终的返回值哟
*/
val f2 :(Int) => Int =(x) => x * 2 /**
* 下面为没有任何参数的匿名函数, 函数的返回值为String类型.
*
*/
val f3:() => String = () => "尹正杰" def main(args: Array[String]): Unit = {
//调用匿名函数f1
var res1 = f1(10)
println(res1) //调用匿名函数f2
var res2 = f1(20)
println(res2) //调用参数为空的匿名函数f3
val Name = f3();
println(Name) }
} /**
* 以上代码执行结果如下 :
* 20
* 40
* 尹正杰
*/
想要了解更多关于函数知识点笔记请参考:https://www.cnblogs.com/yinzhengjie/p/9352798.html。