高阶函数
可以接受函数作为参数的函数成为高阶函数
示例
//test 是一个高阶函数,可以接受一个(入参double返回值double)函数,和一个double参数
def test(f:Double=>Double,n1:Double) ={
f(n1)
}
//普通函数 接受double返回double
def sum2(d:Double):Double={
println("翻倍函数被调用~~")
return d+d
}
//高阶函数 接受一个无入参无返回值的函数
def test2(f:()=>Unit)= {
f()
}
//普通函数
def sayOk()={
println("ok~~~")
}
def main(args: Array[String]): Unit = {
//使用示例1
val ttt=test(sum2 ,3.5)
println(ttt)//7.0
//使用示例2
test2(sayOk)
}
map映射操作
map映射操作集合元素示例
var list =List(1,2,3);
def dble(p:Int):Int={
p+p
}
var list2 = list.map(dble)
println(list)//List(1, 2, 3)
println(list2)//List(2, 4, 6)
list.map(dble) 做了什么
1)将list集合依次遍历
2)将各个元素传递给 dble函数 得到新的元素
3)将得到的新元素放到新的集合中 返回
flatMap映射
flatmap映射 flat 压扁压平
该映射效果就是将结合中每个元素的子元素,映射到某个函数并返回新的集合
示例
var names = List("Alice","Bob","Nick");
def upper(p:String):String={
p.toUpperCase()
}
var names2 = names.flatMap(upper)
println(names2)//List(A, L, I, C, E, B, O, B, N, I, C, K)
filter
将符合要求的元素放到新的集合中,示例如下:
def startsA(str:String):Boolean={
str.startsWith("A")
}
var names3 = names.filter(startsA)
println(names3)//List(Alice)
reduce
将二元函数应用于集合中的元素
def sum (a:Int,b:Int): Int ={
a+b
}
var l1= List(2,3,4,5);
var res = l1.reduceLeft(sum)
println("res:"+res) //res:14
fold
fold 函数将上一步返回值作为函数的第一个参数继续传递与运算,直到list中素有的元素被遍历
可以吧reduceLeft 看做 简化版的 foldLeft 相关函数:fold foldLeft foldRight
示例
def minus(n1:Int,n2:Int): Int ={
n1-n2
}
/*
步骤分析:
println(l1.foldLeft(5)(minus)) 效果等同于 list(5,2,3,4,5) list.reduceLef(minus)
1.5-2=3
2.3-3=0
3.0-4=-4
4.-4-5=-9
*/
println(l1.foldLeft(5)(minus))//-9
/*
步骤分析:
println(l1.foldRight(5)(minus)) 效果等同于 list(2,3,4,5,5) list.reduceRight(minus)
1.5-5=0
2.4-0=4
3.3-4=-1
4.2-(-1)=3
*/
println(l1.foldRight(5)(minus)) //3
//foldLeft 和 foldRight 缩写方法是 /: 和 :\ 编辑器提示已过期
scan
对某个集合中所有的元素做fold操作,但是会吧生产的所有中间结果放置在一个集合中保存
//过程 5(1,2,3,4,5) (5,4,2,-1,-5,-10)
val i8 =(1 to 5).scanLeft(5)(minus)
println(i8)//Vector(5, 4, 2, -1, -5, -10)
//过程 (1,2,3,4,5)5 (20, 19, 17, 14, 10, 5 )
val i9 =(1 to 5).scanRight(5)(sum)
println(i9)//Vector(20, 19, 17, 14, 10, 5)
zip
开发中 当我们需要将两个集合进 对偶元组合并,可以使用拉链
拉链使用注意事项
1)拉链的本质就是两个集合的合并操作,合并后元素编程一个对偶元组
2)如果两个集合个数不对应,会造成数据丢失
3)集合不限于List 也可以是其他集合如Array
4)如果要取出合并后的各个对偶元组的数据,可以遍历
示例
val ll1=List(1,2,3);
val ll3 = List("one","tow","three");
val ll4 = ll1.zip(ll3)
println(ll4)//List((1,one), (2,tow), (3,three))
迭代器
通过 iterator方法从集合中获得一个迭代器,通过while循环 和 for表达式进行遍历
示例
var iter01= List(1,2,3,4,5).iterator
while(iter01.hasNext){
println(iter01.next())
}
iter01= List(1,2,3,4,5).iterator
for(item<-iter01){
println(item)
}
流 Stream
stream 是一个集合,这个集合可以用于存放无穷多个元素但是这无穷多个元素并不会一次性生产出来,
而是要用到多大的区间,就动态的生产,末尾元素遵循lazy规则
示例
//Stream 集合存放的数据类型是BigInt
//numsForm 是一个自定义的函数,创建的集合第一个元素时n ,后续元素生成规则是 N+1
//后续元素生成规则是可以指定的 比如 numsForm(n*4)
def numsForm(n:BigInt):Stream[BigInt] = n #::numsForm(n+1)
val stream1 = numsForm(1)
println(stream1)//Stream(1, ?)
println("stream1.head="+stream1.head)//1
println("stream1.tail="+stream1.tail)//stream1.tail=Stream(2, ?)
println(stream1)//Stream(1, 2, ?)
视图 View
Stream 的懒加载特性,也可以对其他集合应用view方法来得到类似的效果.
1)view 方法产出一个总是被懒执行的集合
2)view 不会缓存数据,每次都要重新计算,比如遍历时
def multi(num:Int):Int={
num
}
//方法 如果翻转后 和原来相等 返回true 否则 返回false
def eq(i:Int):Boolean={
println("eq 被调用....")
i.toString.equals(i.toString.reverse)
}
//不使用view
val viewSquare = (1 to 100).filter(eq)
println(viewSquare)
val viewSquare2 = (1 to 100).view.filter(eq)
println(viewSquare2)
//遍历
for(item <- viewSquare2){
println("item:"+item)
}
并行集合
1)scala 为了充分使用多核心CPU,提供了并行集合,用于多核环境的并行计算
2)主要用到的算法有
a)divide and conquer :分治算法,Scala通过分解器,组合器 将计算任务分解成很多任务,分发给一些处理器去完成
并将它们的处理结果合并后进行返回
b)work stealin 工作窃取算法,主要用于任务调度负载均衡,一个线程完成自己的工作后,可以继续处理其他线程为完成的工作。
val resul1 = (0 to 100).map{case_ => Thread.currentThread().getName}.distinct
val resul2 = (0 to 100).par.map{case_ => Thread.currentThread().getName}.distinct
println(resul1);//非并行
println("-------------------")
println(resul2)//并行
操作符
注意事项
1)如果想在变量名、类名等定义中使用语法关键字,可以配合翻译好使用 如 val val
=""
2)中置操作符 A 操作符 B 等同于 A.操作符(B)
3)后置操作符:A 操作符 等同于 A.操作符
4)前置操作符: +、-、!等操作符 A 等同于 A.unary_操作符
5)复制操作符:A 操作符=B 等同于 A=A 操作符B ,
var n1 =1;
var n2 = 3;
val r1 = n1+n2//3
val r2=n1.+(n2)//3
val mon = new Monster
mon+10
mon.+(10)
println("money:"+mon.money)//20
println(mon++)
println(mon.++)
println("money:"+mon.money)//22
!mon
println("money:"+mon.money)//-22
class Monster{
var money:Int =0
//对+操作符进行重载
def +(n:Int): Unit ={
this.money+=n
}
def ++(): Unit ={
this.money+=1
}
def unary_!(): Unit ={
this.money = -this.money
}
}