1.课程目标
- 1.1 目标1:熟练使用scala编写Spark程序
- 1.2 目标2:动手编写一个简易Spark通信框架
- 1.3 目标3:为阅读Spark内核源码做准备
2.Scala概述
2.1 什么是Scala
- Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。
2.2 为什么学习Scala
- 优雅,速度快,Scala语言表达能力强,一行代码抵得上Java多行,开发速度快;Scala是静态编译的,所以和JRuby,Groovy比起来速度会快很多。
- 能融合到Hadoop生态圈:Hadoop现在是大数据事实标准,Spark并不是要取代Hadoop,而是要完善Hadoop生态。JVM语言大部分可能会想到Java,但Java做出来的API太丑,或者想实现一个优雅的API太费劲。
3. Scala编译器的安装
3.1 安装JDK
- 因为Scala是运行在JVM平台上的,所以安装Scala之前要安装JDK
3.2 安装Scala
3.2.1 Windows安装Scala编译器
- 访问Scala官网http://www.scala-lang.org/下载Scala编译器安装包,目前最新版本是2.12.x,这里下载scala-2.11.8.msi后点击下一步就可以了。
3.2.2 Scala开发工具安装
- 下载IEDA的scala插件,地址https://plugins.jetbrains.com/plugin/1347-scala
4. Scala基础
4.1 声明变量
- val:定义的变量值是不可变的,相当于java里用final修饰的变量
- var:定义的变量是可变得,在Scala中鼓励使用val
Scala编译器会自动推断变量的类型,必要的时候可以指定类型
//变量名在前,类型在后 val str: String = "wwww.mn1024.cn"
4.2 常用类型
- Scala和Java一样,有7种数值类型Byte、Char、Short、Int、Long、Float和Double(无包装类型)和一个Boolean类型
4.3 条件表达式
package cn.mn1024.scala object ConditionDemo { def main(args: Array[String]): Unit = { val x = 1 //判断x的值,将结果赋给y val y = if (x > 0) 1 else -1 //打印y的值 println(y) //支持混合类型表达式 val z = if (x > 1) 1 else "error" //打印z的值 println(z) //如果缺失else,相当于if (x > 2) 1 else () val m = if (x > 2) 1 println(m) //在scala中每个表达式都有值,scala中有个Unit类,写做(),相当于Java中的void val n = if (x > 2) 1 else () println(n) //if和else if val k = if (x < 0) 0 else if (x >= 1) 1 else -1 println(k) } }
4.4 块表达式
package cn.mn1024.scala object BlockExpressionDemo { def main(args: Array[String]): Unit = { val x = 0 //在scala中{}中包含一系列表达式,块中最后一个表达式的值就是块的值 //下面就是一个块表达式 val result = { if (x < 0){ -1 } else if(x >= 1) { 1 } else { "error" } } //result的值就是块表达式的结果 println(result) } }
4.5 循环
- 在scala中有for循环和while循环,用for循环比较多
for循环语法结构:for (i <- 表达式/数组/集合)
package cn.mn1024.scala object ForDemo { def main(args: Array[String]): Unit = { //for(i <- 表达式),表达式1 to 10返回一个Range(区间) //每次循环将区间中的一个值赋给i for (i <- 1 to 10) println(i) //for(i <- 数组) val arr = Array("a", "b", "c") for (i <- arr) println(i) //高级for循环 //每个生成器都可以带一个条件,注意:if前面没有分号 for(i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " ") println() //for推导式:如果for循环的循环体以yield开始,则该循环会构建出一个集合 //每次迭代生成集合中的一个值 val v = for (i <- 1 to 10) yield i * 10 println(v) } }
4.6 定义方法和函数
def 方法名(参数类型和个数): 返回值类型 = 方法体
// 方法的返回值类型可以不写,编译器可以自动推断出来,但是对于递归函数,必须指定返回类型 def m1 (x: Int, y: Int): Int = x * y
val 函数名 = (参数类型和个数) => 函数体
val f1 = (x: Int, y: Int) => x + y
方法和函数的区别是什么:
- 函数可以像任何其他数据类型一样被传递和操作,函数是一个对象
- 函数对象有apply,,curried,,toString,tupled这些方法,而方法不具有这些特性
- 函数= 方法 _
5. 数组、映射、元祖、集合
5.1 数组
可变: import scala.collection.mutable._
- val arr = ArrayBuffer[T]()
不可变:import scala.collection.immutable._
- val arr = new Array[T](数组长度)
数组中如何获取元素
- arr(index)
遍历数组的元素
- 增强for循环
- 好用的until会生成脚标,0 until 10 包含0不包含10
5.2 映射
- 在Scala中,把哈希表这种数据结构叫做映射
构建映射
- val map = Map(键->值,键->值....)
- 利用元组构建 val map = Map((键,值),(键,值),(键,值)....)
注意事项
- 注意:在Scala中,有两种Map,一个是immutable包下的Map,该Map中的内容不可变;另一个是mutable包下的Map,该Map中的内容可变
- 注意:通常我们在创建一个集合是会用val这个关键字修饰一个变量(相当于java中的final),那么就意味着该变量的引用不可变,该引用中的内容是不是可变,取决于这个引用指向的集合的类型
5.3 元组
- 就是用一个()包含的一系列的元素
- val tuple = ("hadoop", 3.14, 1000)
- tuple._1
- tuple._2
5.4 集合
- Scala的集合有三大类:序列Seq、Set、映射Map
- 在Scala中集合有可变(mutable)和不可变(immutable)两种类型,immutable类型的集合初始化后就不能改变了(注意与val修饰的变量进行区别)
6. 类、对象、 继承、特质
7. 模式匹配和样例类
- 匹配字符串
- 匹配类型
- 匹配数组
- 匹配集合
- 匹配元组
匹配样例类
- case class:多例的
- case object:单例的
Option类型
- Some:有值
- None:无值
偏函数
- 定义一个偏函数的时候:已经规定好输入和输出参数的类型(范围)
8. Scala中的协变、逆变、非变
- 协变 C[+T]: 如果A是B的子类,那么C[A]是C[B]的子类。
- 逆变 C[-T]: 如果A是B的子类,那么C[B]是C[A]的子类。
- 非变 C[T]: 无论A和B是什么关系,C[A]和C[B]没有从属关系。
9. 上下界
- 上界: U >: T
- 这是类型下界的定义,也就是U必须是类型T的父类(或本身,自己也可以认为是自己的父类)。
- 下界:S <: T
- 这是类型上界的定义,也就是S必须是类型T的子类(或本身,自己也可以认为是自己的子类)。
10. Scala Actor并发编程
- Scala中的Actor能够实现并行编程的强大功能,它是基于事件模型的并发机制,Scala是运用消息的发送、接收来实现高并发的。
消息发送方式:
- ! : 发送异步消息,没有返回值。
- !!: 发送异步消息,返回值是 Future[Any]。
- !?: 发送同步消息,等待返回值。(Any)
- 注意:Any 是所有类的超类,Future[Any]的泛型是异步操作结果的类型。
11. scala中的高阶函数
作为值的函数
- val list = List(1, 2, 3, 4)
- val func = (x: Int) => x * 10
- list.map(func)
匿名函数
- list.map(x = > x * 10)
柯里化
- def mm(x: Int,y: Int,z: Int) = x + y + z
使用柯里化定义
- def mm(x: Int)(y: Int)(z: Int) = x + y + z
闭包
- 定义函数的时候,此时函数的返回值依赖于不在函数作用域之内的自由变量
- val y = 10
- val func =(x: Int)=> x + y
隐式转换和隐式参数
- 隐式转换
- 隐式参数
12. akka
- 利用akka实现2个进程之间的通信
- 利用akka实现一个简易版的spark通信框架
每一个成功的背后都有无数个无人知晓的黑夜。
因为
夜晚,是超越对手的最佳时机。
===================== 码农1024 =====================#蔺光岭#
还不快抢沙发