Scala函数编程高级偏函数、匿名函数、高阶函数、闭包

偏函数

偏函数专门实现对集合元素的过滤+操作的。
实现需求: 对集合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

猜你喜欢

转载自blog.csdn.net/zhangxm_qz/article/details/107989869