第七章 Scala编程基础
Scala是Scalable Language的简写,是一门多范式的编程语言,由联邦理工学院洛桑(EPFL)的Martin Odersky于2001年基于Funnel的工作开始设计,设计初衷是要集成面向对象编程和函数式编程的各种特性。因此Scala是一种面向对象的语言,每个值都是对象。同时Scala也是一种函数式编程语言,其函数也能当成值来使用。由于Scala整合了面向对象语言和函数式编程的特性,Scala相对于Java、C#、C++等其他语言更加简洁。
Scala源代码被编译成Java字节码,所以它可以运行于JVM之上,并可以调用现有的Java类库。Scala一开始就打算基于Java的生态系统发展自身,而这令Scala受益匪浅。
多范式:
编程范式是指编程时的指导思想。放在编程语言里,则代表了这个语言的设计方向,即语言是为了便于遵循某种,或某些思想编程而设计的。多范式编程语言中的多范式,是指这个语言支持使用者采用多种不同的编程范式来撰写程序。
C语言是过程式编程语言;Java、C#是面向对象式编程语言;Haskell是函数式编程语言;而C++则是多范式的编程语言。
C++非常灵活,并不拘泥于某一种特定的编程方法论。一个编程语言属于某种类型,并不代表这个语言只能用哪种思想编程。比如C语言,虽然是过程式,但我们仍然可以利用struct抽象出class的概念,用函数指针和算法模拟面向对象里的多态特征,只是会非常麻烦。而多范式语言则可以在它所支持的这些范式之间自由切换,不会有勉强的生涩感。当然,代价就是多范式语言一般相对复杂一些。
Scala一开始就打算基于Java的生态系统发展自身:
Martin Odersky之前工作于Java泛型和javac
一、Scala运行环境安装(Windows)
1 检查Java运行环境是否配置
1) 确保本地已经安装了 JDK 1.6 以上版本,并且设置了 JAVA_HOME 环境变量及 JDK 的 bin 目录;
2) 通过命令窗口的方式检测Java运行环境安装配置成功;
1.查看是否安装并配置了Java
2.看是否安装了 Java 编译器
如果尚未安装,可参考:https://www.runoob.com/java/java-environment-setup.html。
2 下载Scala二进制安装包
1) 下载网址:https://www.scala-lang.org/download/ 网址底部位置
2) 找到相应的下载链接
3)选择合适的文件进行下载
3 安装Scala
直接双击下载的msi文件,一步步安装即可,安装过程可以使用默认的安装目录。
使用D:\scala
4 配置环境变量
1)右击我的电脑,单击"属性",进入如图所示页面。下面开始配置环境变量,右击【我的电脑】--【属性】--【高级系统设置】--【环境变量】,如图:
2)设置 SCALA_HOME 变量:单击新建,在变量名栏输入:SCALA_HOME: 变量值一栏输入:D:\Program Files(x86)\scala 也就是 Scala 的安装目录,根据个人情况有所不同。
应当安装在不带空格的目录,比如D:\scala
3) 设置 Path 变量:找到系统变量下的"Path"如图,单击编辑。在"变量值"一栏的最前面添加如下的路径:
%SCALA_HOME%\bin;%SCALA_HOME%\jre\bin;
【注意】后面的分号;不要漏掉。
4)设置 Classpath 变量:找到系统变量下的"Classpath"如图,单击编辑,如没有,则单击"新建":
"变量名":ClassPath
"变量值":
.;%SCALA_HOME%\bin;%SCALA_HOME%\lib\dt.jar;%SCALA_HOME%\lib\tools.jar.;
【注意】"变量值"最前面的 .; 不要漏掉。
5 检查环境变量是否配置成功
1)通过命令窗口的形式检查环境变量是否配置成功
2)如果显示上图界面的信息则说明配置成功。
3)若出现以下信息,请卸载安装好的scala,重新安装在不带空格的目录下如D:\scala\
6 交互式编程HelloWorld
1) 在命令窗口scala提示符后输入相应的简单代码即可进行检测。
二、Scala运行环境安装(Linux)
1 检查Java运行环境是否配置
1) 在Windows系统 PC机上通过VMware Workstation工具打开虚拟机,虚拟机的系统是CentOS7。
2) 在Windows PC机上通过xshell工具远程连接到虚拟机,检查虚拟机中JDK是否安装。
查看JDK是否安装命令与window相同,如果出现上图界面则说明虚拟机JDK已安装。
如果虚拟机环境的JDK未安装,则运行如下步骤:
(可参考:https://blog.csdn.net/dhr201499/article/details/81626466)
1.下载jdk安装包(选择jdk-8u111-linux-x64.tar.gz)
下载网址:
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
2.安装jdk
首先将安装包jdk-8u111-linux-x64.tar.gz上传到虚拟机/usr/local下解压之后重命名为jdk。
然后修改环境变量:编辑文件/etc/profile,在文件底部添加环境变量
2 下载Scala二进制安装包
1) 下载网址:http://www.scala-lang.org/download/
2) 找到相应的下载链接
3) 选择合适的版本直接下载即可
3 安装Scala
1) 将安装包上传到虚拟机/usr/local目录下解压,解压后将文件夹重命名为“scala”
4 配置环境变量
修改环境变量,编辑文件/etc/profile,在此文件的末尾JDK环境变量信息下增加scala环境变量配置内容:
配置完成需要使用命令“source /etc/profile”将配置信息生效。
5 检测scala环境是否安装配置成功
直接输入scala命令即可检测scala安装配置是否成功。
如果出现上图界面,则说明scala环境安装配置成功,接下来可以直接通过命令行的形式编写scala程序了。
三、Scala编程基础语法
1 交互式、脚本形式编写Scala程序
1) 交互式编程
1.Windows + r 打开运行会话框,输入cmd进入命令行窗口
2.命令提示符后输入scala回车进入交互式编程模式
3.输入简单的scala语法进行验证
2) 脚本形式编程
1.通过文本编辑器编写一个scala程序,文件命名为:HelloWorld.scala,程序代码如下:
object HelloWorld {
/* 这是我的第一个 Scala 程序
* 以下程序将输出'Hello World!'
*/
def main(args: Array[String]) {
println("Hello, world!") // 输出 Hello World
}
}
将此文件存放在:D:\scalaWork(参考目录,可修改)
2.使用scalac命令编译此程序
3.检查生成的class文件
4.使用scala命令运行程序
2 Scala中的变量、常量的声明
1)声明变量前掌握scala中的数据类型,Scala中的数据类型与Java数据类型基本一致。
2)变量的声明
3) 常量的声明
常量的值不允许修改,如果尝试修改其值则程序报错。
3 Scala中的运算符号
1) 算术运算符(+ - * / %)
2) 关系运算符(> < >= <= == !=)
3) 逻辑运算符(&& || !)
4) 赋值运算符(= -= += *= /= %= 等)
四、Scala编程基础(数组)
1 数组的声明
1) 一位数组的声明
1.声明
2.赋值
3.另一种数组声明的方式
2)多维数组的声明
多维数组一个数组中的值可以是另一个数组,另一个数组的值也可以是一个数组。矩阵与表格是我们常见的二维数组。
3) 数组中元素的获取(通过下标获取)
2 数组的操作(遍历数组、合并数组)
1.遍历一维数组
新建ArrayDemo.scala文件,代码如下:
object ArrayDemo { def main(args: Array[String]) { var myList = Array(1.9, 2.9, 3.4, 3.5) // 输出所有数组元素 for ( x <- myList ) { println( x ) } // 计算数组所有元素的总和 var total = 0.0; for ( i <- 0 to (myList.length - 1)) { total += myList(i); } println("总和为 " + total); // 查找数组中的最大元素 var max = myList(0); for ( i <- 1 to (myList.length - 1) ) { if (myList(i) > max) max = myList(i); } println("最大值为 " + max); } }
编译并执行,执行结果如下:
2.数组的合并
新建ArrayCombine.scala文件,代码如下:
import Array._ object ArrayCombine { def main(args: Array[String]) { var myList1 = Array(1.9, 2.9, 3.4, 3.5) var myList2 = Array(8.9, 7.9, 0.4, 1.5) var myList3 = concat( myList1, myList2) // 输出所有数组元素 for ( x <- myList3 ) { println( x ) } } }
编译并执行,执行结果如下:
3.数组的连接
与数组的合并原理相同,使用++操作符即可。
五、ScalaIDE for Eclipse开发工具
1 ScalaIDE for Eclipse开发工具下载
1) 下载ScalaIDE for Eclipse网址:
http://scala-ide.org/download/sdk.html
2) 选择相应的链接进行下载
【注意】此版本的Eclipse需JDK1.8及以上版本
2 解压下载的安装包(免安装版本)
将下载的安装包放于PC机的某工作盘,进行解压,解压后的目录:
3 已有Eclipse的引入Scala插件即可
注意ScalaIDE并不是一个独立的IDE,它只是Eclipse的一个插件。如果已经安装Eclipse的,引入相关插件即可。
Eclipse太新的版本包括4.8 4.9 4.10等都不能很好的和scala兼容,如果你的是新版本,请回到前面内容,直接下载安装ScalaIDE for Eclipse
引入过程:选择Eclipse的菜单项Help->Install New Software,拷贝http://download.scala-ide.org/sdk/lithium/e44/scala211/stable/site到Work with输入框中,一步一步安装。
4 创建scala本地工作目录
在个人电脑PC机的某个磁盘目录下创建工作空间(工作目录),如:D:\scalaWork(参考目录,根据自己的需要选择)
5 双击运行eclipse.exe
选择已创建的工作目录
点击“launch”
6 创建Scala项目
1)菜单栏, File –》 new –》 Scala Project
2)输入scala项目名:
3)点击“Finsh”
4)创建scala包
5)在该包下创建第一个scala类
定义一个类名称:
点击“Finsh”
6)类中定义main函数
使用Eclipse中的快捷方式, 输入 main 然后 按Alt + / , 自动补全 Scala 的main 函数。
在函数体内写一条打印语句:
运行 , Run AS –》 Scala Application, 控制台打印如下图:
六、Scala编程基础(方法和函数)
1 自定义方法(带参数有返回值)并完成方法调用
1) 在Eclipse中新建类MaxTest.scala
2) 在此类中依据自定义方法的语法结构创建方法max()。
自定义方法的语法结构如下:
自定义方法的代码如下:
3)定义main方法调用max()进行测试
4) 运行程序,控制台输出如下结果:
2 自定义方法(不带参数不具有返回值)并完成方法调用
1)定义方法
2)方法调用测试
3)程序运行结果
3 嵌套函数的定义并完成函数调用
1)定义函数
2)调用函数进行测试
3)函数运行结果
七、Scala分支判断与循环
1 Scala分支判断结构(判断某年是否为润年,计算某月份的天数)
1) Eclipse中新建scala Object:BranchJudgement.scala
2) 在此文件中自定义方法judge(),方法的返回类型是Boolean,方法的参数为整型的年份;
方法定义如下:
/** * 根据输入的年份判断是否是闰年 */ def judge(year :Int) :Boolean = { if (year % 400 == 0) { return true } if (year % 4 == 0 && year % 100 != 0){ return true }else return false }
3) 定义main方法进行调用测试
【注意】需要import scala.io.StdIn
def main(args: Array[String]): Unit = { println("please input year:") var year = StdIn.readInt() if(judge(year)){ println(year + "是闰年"); }else{ println(year + "不是闰年"); } }
4)执行结果:
5)定义计算某月份的天数的方法
/** * 根据输入的年份、月份判断当月有多少天 */ def getNowMonthDays(year:Int,month:Int):Int = { if (month == 4 || month == 6 || month == 9 || month == 11){ return 30 }else if (month == 2){ return if(judge(year)) 29 else 28 }else return 31 }
6) 调用方法进行测试
7) 运行结果:29
2 Scala循环结构(for循环-求和计算)
1) Eclipse中新建scala Object:LoopExamples.scala
2) 熟悉for循环的语法结构:
其中:Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x 赋值。
3) 在main方法中直接写程序实现求和计算
4) 运行结果:1~100的和是:5050
3 Scala循环结构(while循环-求和)
1)在步骤二的LoopExamples.scala中添加方法sum,参数返回值类型Int:
2)调用方法测试:
3)运行结果:1~100的和是:5050
4 Scala循环结构(do while循环-求和)
1)在步骤二的LoopExamples.scala中添加方法add,参数返回值类型Int:
2)调用方法测试:
3)运行结果:1~100的和是:5050
八、Scala 列表
1 List的创建与声明
1) Eclipse中新建scala Object:ListOperator.scala
2) 在main方法中声明不同类型的List
2 List中简单方法的运用(head方法、tail方法、isEmpty方法)
1)在以上程序中追加代码:
2)程序运行结果
3)完成对以上列表的操作(tail方法、isEmpty方法)
3) 程序运行结果:
3 List中的其他方法运用(连接列表)
1)熟知列表连接的含义:连接两个或多个列表。
2)在步骤1定义的Scala Object :ListOperator.scala中定义方法完成两个列表的合并操作。
3)调用方法进行测试:
4)运行结果:
4 List中的其他方法运用(fill方法)
1)熟知fill方法的含义:使用 List.fill() 方法来创建一个指定重复数量的元素列表。
2)在步骤1定义的ListOperator.scala中定义方法完成fill方法的运用
3)调用方法进行测试:
4)运行结果:
5 List中的其他方法运用(tabulate方法)
1)熟知tabulate方法的含义:通过给定的函数来创建列表,方法的第一个参数为元素的数量,可以是二维的,第二个参数为指定的函数,我们通过指定的函数计算结果并返回值插入到列表中,起始值为 0。
2)在步骤1定义的ListOperator.scala中定义方法完成tabulate方法的运用。
3)调用方法进行测试:
4)运行结果:
6 List中的其他方法运用(reverse方法)
1)熟知reverse方法的含义:反转列表
2)在步骤1定义的ListOperator.scala中定义方法完成reverse方法的运用。
3)调用方法进行测试:
4)运行结果:
九、Scala Set集合
1 集合的创建
1)在Eclipse中新建Scala Object:SetOperator.scala。
2)在此文件的main方法中创建set集合(不可变集合、可变集合)
3)运行程序打印两个集合的信息
2 可变集合中元素的动态添加、删除及类型转换
1)在步骤1创建的文件的main方法中完成对集合set02元素的动态添加、删除等操作
2)程序运行结果:
3 集合set的基本方法运用(head、tail、isEmpty)
1)在步骤1创建的文件中创建方法setFunction(),完成对声明的set集合变量head、tail、isEmpty方法操作
2)调用方法进行测试:
3)程序运行结果:
4 集合set的其他方法运用(连接集合)
1)掌握set集合的连接语法:使用 ++ 运算符或 Set.++() 方法来连接两个集合。如果元素有重复的就会移除重复的元素。
2)在步骤1定义的文件中定义方法完成两个set集合连接操作。
3)调用方法进行测试:
4)运行结果:
5 集合set的其他方法运用(求最大、最小值、交集)
1)熟知set集合求最大、最小值以及交集的方法名分别为:min、max、intersect。
2)在步骤1定义的文件中定义方法完成以上三个方法的运用
3)调用方法进行测试:
4)运行结果:
十、Scala Map映射
1 Map的声明
1)在Eclipse中新建Scala Object:MapOperator.scala。
2)在文件的main方法中创建Map(不可变Map、可变Map)
3)程序运行结果:
2 Map的基本操作(keys、values、isEmpty)
1)在步骤1创建的文件的main方法中练习Map的基本方法keys、values和isEmpty。
2)程序运行结果:
3 Map其他方法的运用(合并)
1)掌握Map映射的合并方法:++ 运算符或 Map.++() 方法来连接两个 Map,Map 合并时会移除重复的 key。
2)在步骤1定义的文件定义方法完成两个Map和合并操作。
3)调用方法测试:
4)程序运行结果:
4 Map值的循环遍历
1)掌握使用foreach 循环输出 Map 中的 keys 和 values。
2)在步骤1定义的文件中定义方法完成Map 键/值的打印输出。
3)调用方法测试:
4)程序执行结果:
5 判断Map中是否含有指定的key值
1)掌握使用 Map.contains 方法来查看 Map 中是否存在指定的 Key。
2)在步骤1定义的文件中定义方法完成Map中是否包含某指定key值的判断。
3)调用方法测试:
4)程序执行结果:
十一、Scala元组
1 元组的创建与访问元素
1)在Eclipse中新建Scala Object:TupleOperator.scala。
2)在此文件的main方法中创建元组并完成元组中元素的访问
3)程序运行结果:
2 元组的基本操作(迭代、转换为字符串、元素交换)
1) 掌握使用元组操作的基本方法
Tuple.productIterator() 迭代
Tuple.toString() 转换为字符串
Tuple.swap 元素交换
2)在步骤1定义的文件中定义方法完成元组的迭代、转换字符串、元素交换方法的运用。
3)调用方法测试:
4)程序执行结果:
十二、 Scala类
1 类的创建
1)掌握Scala类的含义:类是对象的抽象,而对象是类的具体实例
2)在Eclipse中创建class类Point
【注】Scala中的类不声明为public,一个Scala源文件中可以有多个类,Scala 的类定义可以有参数,称为类参数,如上面的 xc, yc,类参数在整个类中都可以访问。
3)类的实例化
Eclipse中新建一个Object PointTest.scala,在main方法中实例化Point对象。
4)程序运行结果:
2 类的继承
1)掌握Scala类继承的注意事项:
1.重写一个非抽象方法必须使用override修饰符。
2.只有主构造函数才可以往基类的构造函数里写参数。
3.在子类中重写超类的抽象方法时,你不需要使用override关键字。
2)在Eclipse中定义类Location继承步骤1中的类Point
【注】Scala 使用 extends 关键字来继承一个类。实例中 Location 类继承了 Point 类。Point 称为父类(基类),Location 称为子类。override val xc 为重写了父类的字段。继承会继承父类的所有属性和方法,Scala 只允许继承一个父类。
3)在步骤1建的PointTest.scala的main方法中进行测试
4)程序运行结果
3 Scala中的Object关键词
1) 掌握Scala中的Object关键词的作用
1.Scala中没有static关键字,因此Scala的类中不存在静态成员。但是Scala可是使用“object”关键字实现单例模式。
2.Scala中使用单例模式时需要使用object定义一个单例对象(object对象),单例对象就是在整个程序中只有这么一个实例。object对象与类的区别在于object对象不能带参数。
3.包含main方法的object对象可以作为程序的入口点
2) 在Eclipse中定义Object Person.scala
3) 程序运行:控制台输出18。
十三、文件的读写操作
1 写文件
1)在Eclipse中创建Object:FileWrite.scala
2) 在此文件的main方法完成文件的写操作
3)程序运行结果:
2 读文件
1) 在Eclipse中创建Object:FileRead.scala
2)在此文件的main方法完成文件的读操作
3)程序运行结果:
3 接收键盘输入
1)在步骤1建立的FileWrite.scala文件的main方法中编写接收键盘输入代码
2)程序运行结果