目录
简介
2004年martin ordersky 发明,javac的编译器,后来spark,kafka应用广泛,twitter应用推广。 它具备面向对象和函数编程的特点 官网:www.scala-lang.org 版本号2.12.5
安装
下一步
知识
基础语法
1、变量(var),常量(val)
变量
格式 var 变量名 [:数据类型] = 值
[注意] 分号可不写,推荐不写,因为要类型自动推断
[注意] 成员变量必须赋初始值,可以用下划线做占位符,系统会赋初始值
常量
格式 val 变量名 [:数据类型] = 值
lazy
格式 var 变量名 [:数据类型] = 值 格式 val 变量名 [:数据类型] = 值 用到时才会赋值
2、数据类型
类型
1 Byte 8位有符号值,范围从-128至127 2 Short 16位有符号值,范围从-32768至32767 3 Int 32位有符号值,范围从-2147483648至2147483647 4 Long 64位有符号值,范围从-9223372036854775808至 9223372036854775807 5 Float 32位IEEE 754单精度浮点值 6 Double 64位IEEE 754双精度浮点值 7 Char 16位无符号Unicode字符。范围从U+0000到U+FFFF 8 String 一个Char类型序列 9 Boolean 文字值true或文字值false
10 Unit 对应于无值,等价于void类型,只有一个对象叫() 11 Null 只有一个对象叫null 12 Nothing 在Scala中处于最底层,比如创建数组时不指定类型,就是 Noting。抽象概念 13 Any 任何类型的超类型; 任何对象的类型为Any 14 AnyRef 任何引用类型的超类型
结构
Any -AnyVal -Int,Double等,Unit -AnyRef -List,Set,Map,Seq,Iterable -java.lang.String -Null
重点类型
元组
格式:(元素1, 元素2, ....) 访问:变量._N 其中N是元组元素的索引,从1开始
例:var t = ("a", false, 1) var value = t._1 //"a" var m,n,(x,y,z) = ("a", false, 1) m :("a", false, 1) n :("a", false, 1) x : "a" y : false z : 1
字符串
i) 用的是java.lang.String,但是有时候根据需要,会隐式转换到其它类型,比如调用reverse/sorted/sortWith/drop/slice等方法,这些方法定义在IndexedSeqOptimized中 ii)多行表示
3、运算符
算术:+ - * / % 比较: == != > < >= <= 逻辑:&& || ! 赋值:= += -= *= /* %= 位:& | ~ ^ >> << >>>
4、控制语句
(1) if,if...else...,if...else if...else... (2) scala中的if可以作为表达式用 var x = if("hello"=="hell") 1 else 0 (3) switch被模式匹配替换
5、循环语句
(1)while,do..while和for都有,while和do..while很像,但是for差别很大。 (2)for循环格式不同 for(变量 <- 集合 if 条件判断1;if 条件判断2...) { 所有条件判断都满足才执行 }
6、集合框架
Array,List,Set,Map
(immutable不可改变的长度,默认) -Set 无序的集合,没有重复元素 HashSet,TreeSt 其中HashSet内部定义了别名Set -Map 键值对,映射 HashMap,TreeMap 其中HashMap内部定义了别名Map -Seq 序列。有先后顺序的元素集合 -IndexedSeq Array:有索引的元素序列,因此可以通过下标访问 Vector,String,Range -LinearSeq List:线性的元素序列。访问第1个元素,head方法,最后1个tail方法 Queue,Stack (mutable可变的长度) -Set HashSet 其中HashSet内部定义了别名Set -Map HashMap 其中HashMap内部定义了别名Map -Seq -IndexedSeq ArraySeq,StringBuilder -Buffer ArrayBuffer,ListBuffer -LinearSeq LinkedList,Queue Stack 不可变 可变 Array ArrayBuffer List ListBuffer Map Map Set Set
函数
Scala中函数和方法,在类中定义的函数就是方法。
1) 函数声明
def 函数名([参数列表]):[返回类型] = { 函数体 return [表达式] } 注1:如果函数没有返回值,可以返回Unit,也可以不写 注2:方法的返回类型可以不写,系统自动推导,但是递归必须写。 注3:函数体的大括号只有一行,可以不写 例: def add(a:Int,b:Int):Int = { var sum : Int = 0 sum = a + b return sum }
2) 函数调用 格式: 方法之间调用:函数名([实参列表]) 例:add(3,5) 对象之间调用:实例名.函数名([实参列表]) 例:s.add(3,5)3) 值函数 (1)定义 var 变量名:[输入类型=>输出类型] = { (参数列表)=>{函数体} } 其中=>是函数映射符 在参数列表后不能写返回值类型 最后一句不能写return
Lambda表达式(匿名函数,函数字面量):形如(参数列表)=>{函数体}就叫Lambda表达式
4) 常见高阶函数
定义:本身是函数,参数也是函数或返回值是函数 例1: def m(f:(Double)=>Double):Double = {f(100)} def sqrt(x:Double)=Math.sqrt(x) 调用m(sqrt) 结果是10.0
map
def map[B, That](f: A => B): That 把函数应用于集合中的每一个元素,把返回由返回值组成的一个集合。
Array("spark","hive","haddop").map((x:String)=>x.length) Array("spark","hive","haddop").map(x=>x.length) Array("spark","hive","haddop").map(_.length) // _占位符,代表一个元素 Array("spark","hive","haddop").map(x=>println(x)) Array("spark","hive","haddop").map(println _) Array("spark","hive","haddop").map(println) //如果只有一个参数,可以不写
flatMap
把函数应用于集合中的每一个元素,先做map,得到的结果flatten,生成新的集合。
var list = List("a,b,c","d,e,f") var list2 = list.map(x=>x.split(",").toList) //List(List(a, b, c), List(d, e, f)) list2.flatten //List(a,b,c,d,e,f) 上面两步可以写成一步,相当于map+flattern list.flatMap(x=>x.split(",").toList) //简写:List.flatMap(_.split(",").toList)
map函数会对每一条输入进行指定的操作,然后为每一条输入返回一个对象 flatMap函数则是两个操作的集合——正是“先映射后扁平化”
filter
参数的函数表示对集合的每个元素过滤,参数函数结果是boolean,最后的返回值还是List
List(1,2,3,4).filter(x=>x>2) //List(3,4) Array(1,2,3,4,5,6,7,8).filter(x=>x%2==0) //取偶数 2,4,6,8 Range(1,100).filter(_%2==0) //1到100的偶数 Array(1,2,3,4,5,6,7,8).filter(x=>x%2==0).map(_*10)//20,40,60,80
filterNot反之
flatten
flatten可以把嵌套的结构展开.
List(List(1,2),List(3,4)).flatten res0: List[Int] = List(1, 2, 3, 4)
reduce
返回1个值。参数函数要求是二元运算符,作用于集合上,每次返回的结果作为新的输入。 Array(1,3,5,7).reduce((x,y)=>{println(x + ":" +y);x+y}) Array(1,3,5,7).reduce(_+_) //第1个_代表第1个参数,第2个_代表第2个参数 Array(1,3,5,7).reduceLeft((x,y)=>{println(x + ":" +y);x+y}) Array(1,3,5,7).reduceRight((x,y)=>{println(x + ":" +y);x+y})
注:reduce和reduceLeft一样,从左到右计算,reduceRigth从右到左计算
fold
和reduce很像,只是增加了一个初始值,但是做并行时要注意。
Array(1,3,5,7).fold(4)(_+_) //20 List(2.0,3.0).fold(4.0)(Math.pow) //4096.0
par
把计算转换为并行化,把reduce拆分多个任务
Array(1,3,5,7,8).par.fold(4)(_+_) Range(1,10).par.map(println)
groupBy
对列表进行分组,返回结果是map
var data = List(("zhang3","male"),("li4","female"),("wang5","male")) data.groupBy(x=>x._2) /Map(male-> List((zhang3,male), (wang5,male)), female -> List((li4,female)))
多介绍一个grouped(n):每n个分成一组 例:List(1,3,5,7,9).grouped(2).toList //List(List(1, 3), List(5, 7), List(9))
partition
把列表分成两部分,第一个为满足条件的,第二部为不满足条件的
List(1,3,5,7,9).partition(x=>x>4) //分成两组:(List(5, 7, 9),List(1, 3))
diff
差集
var n1 = List(1,2,3) var n2 = List(2,3,4) var n3 = n1.diff(n2) //也可以写n1 diff n2 ,结果:List(1) var n4 = n2.diff(n1) //List(4)
union
并集并保留重复
var n1 = List(1,2,3) var n2 = List(2,3,4) var n5 = n1 union n2 //List(1 2 3 2 3 4)
intersect
交集
var n1 = List(1,2,3) var n2 = List(2,3,4) var n6 = n1 intersect n2 //List(2,3)
distinct
去掉重复元素
List(1,2,3,2,3,4).distinct // List(1, 2, 3, 4)
mapValues
还是map功能,只是处理的值是value,最终结果是map
Map(("zhang3",20),("li4",23),("wang5",21)).mapValues(_*2) //结果 Map(zhang3 -> 40,li4 -> 46,wang5 -> 42)
sorted
排序,最简单,从小到大
List(2,1,3,5,6,4).sorted //1 2 3 4 5 6
sortBy
按照第几列排
List(("a",3),("b",1),("c",2)).sortBy(_._2) //按照第2列排
sortWith
自定义排序
List(2,1,3,5,6,4).sortWith((x,y)=>x>y) //从大到小
sleep
睡眠
Thread.sleep(2000)
Scala Actor
Scala中的Actor能够实现并行编程的强大功能,它是基于事件模型的并发机制,Scala是运用消息(message)的发送、接收来实现多线程的。使用Scala能够更容易地实现多线程应用的开发。
选择接收结果
! | 发送异步信息,不接返回值 |
---|---|
!? | 发送异步信息,等待返回值 |
!! | 发送异步信息,返回值是Future[Any] |
使用方法
A
react方式会复用线程,比receive更高效
import scala.actors.Actor class MyReact extends Actor { override def act(): Unit = { while (true) { react{ case "start"=>{ println("starting...") Thread.sleep(2000) println("startd") Thread.sleep(2000) } case "stop"=>{ println("stopping ...") Thread.sleep(2000) println("stopped") } } } } }
B
object test_receive_act { def main(args: Array[String]) { val actor = new MyReact actor.start() actor ! "start" actor ! "stop" println("消息发送完成!") } }