偏函数
偏函数专门实现对集合元素的过滤+操作的。
实现需求: 对集合List(1,2,3,4,“abc”) 中的 int类型+1 后加入到新的集合, 其他类型元素舍弃
五种实现方式对比
def test: Unit ={
val list =List(1,2,3,4,"abc");
//实现对 list 中int类型 进行 +1操作 并返回新的数组
//实现方式1 filter+map
println("方式1:"+list.filter(f1).map(f3).map(f2));
//实现方式2 模式匹配
println("方式2:"+list.map(addOne))
//以上两种方式 都不够简洁
//方式3 偏函数
//偏函数中定义两个方法 isDefinedAt 和 apply方法
//执行过程 1.遍历集合中的元素
// 2.调用parFun的isDefinedAt 方法 如果该方法返回为true 则 调用 apply方法 并将新元素添加到一个新的集合
//定义一个 偏函数 泛型表示 接受 任意类型 返回 Int类型
val parFun = new PartialFunction[Any,Int] {
override def isDefinedAt(x: Any): Boolean = {
x.isInstanceOf[Int]
}
override def apply(x: Any) = {
x.asInstanceOf[Int]+1
}
}
//对集合执行偏函数
println("方式3:"+list.collect(parFun))
//偏函数简写形式
//简写成一个对象的形式
def parFun2:PartialFunction[Any,Int] = {
case in:Int =>in+1
case d:Double =>d.toInt
}
//对集合执行偏函数
println("方式4:"+list.collect(parFun2))
//偏函数简写形式2
//简写成一个对象的形式
//对集合执行偏函数
println("方式5:"+list.collect{
case in:Int =>in+1
case d:Double =>d.toInt
})
}
def f1(n:Any):Boolean={
n.isInstanceOf[Int]
}
def f2(n:Int):Int={
n+1
}
def f3(n:Any):Int={
n.asInstanceOf[Int]
}
def addOne(n:Any):Any={
n match{
case x:Int =>x+1
case _ =>
}
}
注意事项
1)map 函数不支持偏函数 ,因为map底层就是遍历循环,无法过滤元素
2)collect 函数支持偏函数
匿名函数
没有名字的函数就是匿名函数,可以通过函数表达式来设置匿名函数
示例
def test: Unit ={
val triple= (x:Double)=>{
3*x
}
println(triple);
println(triple(3));
}
高阶函数
能够接受函数作为参数的函数叫做高阶函数
示例
def test: Unit ={
//定义test1 方法 接受两个方法f f2 和一个 double类型参数
def test1(f:Double=>Double,f2:Double=>Int,n1:Double)={
f(f2(n1))
}
def sum(d:Double):Double= d+d
def mod(d:Double):Int = d.toInt%2
println(test1(sum,mod,3))
//高阶函数可以返回一个函数
def minusxy(x:Int)={
(y:Int)=>x-y
}
//分步调用 先调用 minusxy(3) 返回一个函数f1 逻辑为 3-y 再调用 f1(4) 返回 3-4 =-1
val f1 = minusxy(3);
println(f1(4)); //-1
//一步到位调用
println(minusxy(3)(4)) //-1
print(f1)
}
参数推断及简写
某些情况下参数类型是可以推断出来的,如List(1,2,3).map() map中的函数参数类型是可以推断出来的,
这种情况下可以进行相应的简写。
1)参数类型可以推断时可以省略参数类型
2)当传入的函数只有单个参数时可以省略括号
3)如果变量只在=>右边出现一次,可以用 _来代替
示例
def test: Unit ={
val list = List(1,2,3,4)
println(list.map((x:Int)=>x+1))//传入一个匿名函数
println(list.map((x)=>x+1))//省略参数类型
println(list.map(x=>x+1))//只有一个参数可以省略括号
println(list.map(_+1))//参数在右侧只出现一次可以使用 _代替
println("---------------------------------")
println(list.reduce(f1))//常规函数写法
println(list.reduce((n1:Int,n2:Int)=>n1+n2))//匿名函数写法
println(list.reduce((n1,n2)=>n1+n2))
//println(list.reduce(n1,n2=>n1+n2))参数数量大于1不能省略参数括号
println(list.reduce(_+_))//参数在右侧只出现一次可以使用 _代替
}
def f1(n1:Int,n2:Int): Int ={
n1+n2
}
闭包
闭包就是 一个函数和与其相关的引用环境组合成的一个整体
示例
def minusxy(x: Int) = (y: Int) => x - y
val f = minusxy(10)
println(f(8))
说明
minusxy 返回一个匿名函数 (y: Int) => x - y,该函数引用到了函数外的变量 x 这样 x 和 该匿名函数就
组成了一个关联的整体,即闭包。
val f = minusxy(10) 函数f 就是个闭包 ,每次调用f时使用的 x d=都是10