一、Scala简介:多范式的编程语言
1、多范式:支持面向对象、支持函数式编程
2、底层依赖JVM
二、安装配置Scala、常用的开发工具
1、安装配置
版本:2.11.8版本跟Spark的版本一致(spark-2.1.0-bin-hadoop2.7.tgz)
scala-2.11.8.zip(Windows)
scala-2.11.8.tgz(Linux)
以windows为例:类似JDK的安装
(1)解压: C:\Java\scala-2.11.8
(2)设置SCALA_HOME: C:\Java\scala-2.11.8
(3)把%SCALA_HOME%/bin加入PATH路径
(4)执行: scala -version
2、常用开发工具
(1)REPL:命令行
退出: :quit
(2)IDEA: 默认没有Scala环境,安装插件SBT(需要联网)
(3)Scala IDE:就是Eclipse
三、Scala的常用数据类型
1、注意:在Scala中,任何数据都是对象。
举例:数字 1 ----> 是一个对象,就有方法
scala> 1.toString
res0: String = 1 ----> 定义了新的变量 res0,类型String
2、Scala定义变量的时候,可以不指定变量的类型,Scala会进行类型的自动推导
举例:下面的语句是一样的
var a:Int = 10
var b = 10
如何定义常量? val
val c = 10
3、数据的类型
(1)数值类型:复习
(*)Byte: 8位的有符号 -128~127
(*)Short:16位的有符号 -32768 ~ 32767
(*)Int: 32位的有符号
(*)Long: 64位的有符号
(*)Float:浮点数
(*)Double:双精度
(2)字符串:Char、String
对于字符串,在Scala中可以进行插值操作
val s1 = "hello world"
可以在另一个字符串中,引用s1的值
"My name is Tom and ${s1}"
(3)Unit类型:相当于Java中的void 类型
()代表一个函数:没有参数,也没有返回值
scala> val f = ()
f: Unit = ()
val f = (a:Int)
(4)Nothing类型:一般来说,表示在函数(方法)执行过程中产生了Exception
举例: 定义函数 def
def myfunction = throw new Exception("some exception ....")
myfunction: Nothing
四、Scala的函数
1、内置函数:数学运算
举例:求最大值
max(1,2)
包: import scala.math._
https://www.scala-lang.org/files/archive/api/2.11.8/#package
scala> max(1,2)
res4: Int = 2 ----> 定义了一个新的变量来保存运算的结果
var result:Int = max(1,2)
var result = max(1,2)
2、自定义函数:def
3、Scala的条件表达式 if.. else
//注意:scala中函数的最后一句话,就是函数分返回值
//不写reture
五、循环: for、while、do...while
//循环
//for循环
//定义集合
var nameList = List("Mary","Mike","Tom")
println("******第一种写法******")
// <- 表示提取符
for(s <- nameList) println(s)
println("******第二种写法******")
//打印长度大于3的名字
//循环的时候加入判断条件
for{
s <- nameList
if(s.length > 3)
}println(s)
println("******第三种写法******")
for(s <- nameList if s.length <=3) println(s)
//使用操作符(关键字)yield 使用循环的每个元素创建一个新的集合
//创建一个新的集合,名字大写
var newNameList = for{
s <- nameList
s1 = s.toUpperCase
}yield(s1)
//使用while 循环
var i = 0
while(i < nameList.length){
println(nameList(i)) //注意:小括号
i += 1
}
六、Scala函数的参数:求值策略
1、call by value:对函数的实参求值,并且仅求一次
举例:def test1(x:Int,y:Int):Int = x+x 没有用到y
2、call by name:函数的实参每次在函数体内部被调用的时候,都会进行求值
举例:def test2(x: => Int,y: =>Int):Int = x+x 没有用到y
3、一个复杂点的例子
x是call by value
y是call by name
def test3(x:Int,y: =>Int):Int = 1
再定义一个死循环的函数
def loop():Int = loop
考虑下面的两个调用
test3(1,loop) ---> 正常
test3(loop,1) ---> 死循环
4、函数的参数:默认参数、代名参数、可变参数
//默认参数
def fun1(name:String="Mary"):String = "Hello " + name
fun1("Tom")
fun1()
//代名参数:如果一个函数具有多个默认参数,使用带名参数区别
def fun2(str:String="Good Morning ",name:String="Mary",age:Int=20)
= str + name + " the age of " +name + " is " + age
fun2(name="Mike")
//可变参数:类似Java,Java中:...
//Scala:使用 *
//求任意个数字的和
def sum(args:Int*) = {
var result = 0
for(arg <- args)
result += arg
//最后一句话就是返回值
result
}
//调用
sum(1,2,3)
sum(1,2,3,4)七、lazy值:如果一个变量被lazy修饰了,他的初始化会被推迟到第一次使用的时候
举例1
scala> var x = 10
x: Int = 10
scala> lazy val y = x + 10
y: Int = <lazy>
scala> y
res0: Int = 20
举例2:读文件(存在)
读文件(不存在)
scala> val words = scala.io.Source.fromFile("d:\\temp\\a.txt").mkString
words: String = I love Beijing scala> val words1 = scala.io.Source.fromFile("d:\\temp\\b.txt").mkString
java.io.FileNotFoundException: d:\temp\b.txt (系统找不到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at scala.io.Source$.fromFile(Source.scala:91)
at scala.io.Source$.fromFile(Source.scala:76)
at scala.io.Source$.fromFile(Source.scala:54)
... 32 elided scala> lazy val words1 = scala.io.Source.fromFile("d:\\temp\\b.txt").mkString
words1: String = <lazy> scala> words1
java.io.FileNotFoundException: d:\temp\b.txt (系统找不到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at scala.io.Source$.fromFile(Source.scala:91)
at scala.io.Source$.fromFile(Source.scala:76)
at scala.io.Source$.fromFile(Source.scala:54)
at .words1$lzycompute(<console>:11)
at .words1(<console>:11)
... 32 elided scala>
八、异常:Exception
try{
val words = scala.io.Source.fromFile("D:\\a.txt").mkString
print(words)
}
catch{
case e1:java.io.FileNotFoundException =>{
print("FileNotFount Exception")
}
case e2:IllegalArgumentException =>{
print("Illegal Argument Exception")
}
case _:Exception =>{
print("Ex...")
}
}finally {
print("=======")
} 九、数组、映射、元组
1、数组:定长数组 Array
变长数组 ArrayBuffer
import scala.collection.mutable.ArrayBuffer
//Scala的数组
//数组:定长数组 Array
val a = new Array[Int](10)
val b = new Array[String](8)
val c = Array("Tom","Mary","Mike")
// 变长数组 ArrayBuffer
val d = ArrayBuffer[Int]()
//增加新的元素
d += 1
d += 2
d += 3
d += 4
//把变长数组转成一个定长数组
d.toArray
//遍历数组
//使用for循环
for(s <- c) println(s)
//使用foreach方法(算子)
//注意:算子map和foreach:都是对集合中的每个元素进行操作
// 区别:foreach没有返回值 map有返回值
c.foreach(println)
2、映射Map、元组Tuple
//映射 Map:不可变的Map 可变的Map
//(key value)
// 使用操作符 ->
val scores = Map("Tom"->80,"Mary"->90,"Mike"->75)
//可变的Map
val chinese = scala.collection.mutable.Map("Tom"->80,"Mary"->90,"Mike"->75)
//常用的操作
//1. 获取值
chinese("Tom")
//获取一个不存在的value
//chinese("Jone") //产生Exception
//可以这么写
if(chinese.contains("Jone")){
chinese("Jone")
}else{
-1
}
//简写的方式
chinese.getOrElse("Jone",-1)
//更新
chinese("Tom")=100
//添加新的元素
chinese += "Jone" -> 95
chinese
//移除元素
chinese -= "Jone"
//迭代映射:for foreach
for(s <- chinese) println(s)
//说明:通过foreach取出chinese中的每个元素,并把这个元素传递给println
chinese.foreach(println)
//元组Tuple:是不同类型的值的聚集
//指定的类型:Tuple3[Int,Double,String]
val t1 = (1,3.14,"Hello")
val t2 = new Tuple3("Mary",100,"Hello")
//取出每个元素 : 第二个元素
t2._2
//t2._4 ---> 出错
//遍历
t2.productIterator.foreach(println)
参考 潭州学院 赵强老师scala 笔记
https://www.shiguangkey.com/video/1763?videoId=14342&classId=1403
















