一、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