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。

Scala进阶之路-Scala的基本语法的更多相关文章

  1. Scala进阶之路-Scala高级语法之隐式(implicit)详解

    Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...

  2. Scala进阶之路-Scala中的高级类型

    Scala进阶之路-Scala中的高级类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.类型(Type)与类(Class)的区别 在Java里,一直到jdk1.5之前,我们说 ...

  3. Scala进阶之路-Scala中的Ordered--Ordering

    Scala进阶之路-Scala中的Ordered--Ordering 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   说道对象的比较,在Java中大家最熟悉不过的就是实现类本身实 ...

  4. Scala进阶之路-Scala中的泛型介绍

    Scala进阶之路-Scala中的泛型介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 通俗的讲,比如需要定义一个函数,函数的参数可以接受任意类型.我们不可能一一列举所有的参数类 ...

  5. Scala进阶之路-Scala特征类与unapply反向抽取

    Scala进阶之路-Scala特征类与unapply反向抽取 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala特征类分析 1>.Unit 答:用于定义返回值类型, ...

  6. Scala进阶之路-Scala中的枚举用法案例展示

    Scala进阶之路-Scala中的枚举用法案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala中的枚举值和Java中的枚举值有点差别,不过使用起来也都差大同小异,我这 ...

  7. Scala进阶之路-Scala函数篇详解

    Scala进阶之路-Scala函数篇详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传值调用和传名调用 /* @author :yinzhengjie Blog:http: ...

  8. Scala进阶之路-高级数据类型之集合的使用

    Scala进阶之路-高级数据类型之集合的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala 的集合有三大类:序列 Seq.集 Set.映射 Map,所有的集合都扩展自 ...

  9. Scala进阶之路-反射(reflect)技术详解

    Scala进阶之路-反射(reflect)技术详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala中的反射技术和Java反射用法类似,我这里就不一一介绍反射是啥了,如果对 ...

随机推荐

  1. libgdx学习记录8——对话框Dialog

    Dialog在游戏中也很常用,尤其在设置.退出.商店.暂停等画面.Dialog的使用也可以通过skin实现,也可以自定义. 下面是一个简单的实例: package com.fxb.newtest; i ...

  2. 《Linux内核分析与设计》读书笔记二

    第五章 5.1 与内核通信57 系统调用在用户空间进程和硬件设备之间添加了一个中间层,该层主要作用有三个: 首先它为用户空间提供了一种硬件的抽象接口,举例来说当需要读写文件的时候,应用程序就可以不去管 ...

  3. sql两个日期之间的查询统计

    sql查询统计 sql语句: select count(code) as '统计',create_time as '订单时间' from sp_orders where datediff(create ...

  4. Alpha冲刺——day3

    Alpha冲刺--day3 作业链接 Alpha冲刺随笔集 github地址 团队成员 031602636 许舒玲(队长) 031602237 吴杰婷 031602220 雷博浩 031602634 ...

  5. beta NO1

    031602111 傅海涛 1.今天进展 笔记颜色统一,解决笔记的同步性和完整性 2.存在问题 office文档转换的时间问题 3.明天安排 增加新功能和完善之前的功能 4.心得体会 接口真难 031 ...

  6. 转帖 OKR

    什么是OKR OKR全称是Objectives and Key Results,即目标与关键成果法.OKR是一套定义和跟踪目标及其完成情况的管理工具和方法.1999年Intel公司发明了这种方法,后来 ...

  7. Android控件第2类——ImageView

    1.ImageView不仅仅可以显示图片,ImageView可以显示任何Drawable对象. adjustViewBounds:设置ImageView是否调整自己的边界来保证图片的长宽比. crop ...

  8. AJAX 原生态

                                                                   AJAX   原生态 原生态AJAX详解和jquery对AJAX的封装 A ...

  9. pgm7

    和 Koller 的 video 最大的不同莫过于书上讲 LBP 的角度不是 procedural 的,而是原理性的.我们先看个 procedural 的,在一般的 cluster graph 上的 ...

  10. BZOJ5287 HNOI2018毒瘤(虚树+树形dp)

    显然的做法是暴力枚举非树边所连接两点的选或不选,大力dp.考场上写的是最暴力的O(3n-mn),成功比大众分少10分.容斥或者注意到某些枚举是不必要的就能让底数变成2.但暴力的极限也就到此为止. 每次 ...