scala中偏函数

偏函数的定义
1)在对符合某个条件,而不是所有情况进行逻辑操作时,使用盘函数是一个不错的选择
2) 将包在大括号的一组case语句封装为函数,我们称之为偏函数,它只对会作用于执行类型的参数或指定范围的参数实施计算,超出范围的值会忽略(未必忽略看具体的逻辑)
3) 偏函数在scala中是一个特质PartialFuncation

提出一个需求,引起思考
给你一个集合val list = List(1, 2, 3, 4, “abc”) ,请完成如下要求:

将集合list中的所有数字+1,并返回一个新的集合
要求忽略掉 非数字 的元素,即返回的 新的集合 形式为 (2, 3, 4, 5)
解决方式-filter + map返回新的集合, 引出偏函数

解决方式-模式匹配

object PartialFunDemo01 {
  def main(args: Array[String]): Unit = {
    //思路1 filter + map 方式解决
    //虽然可以解决问题,但是麻烦.
    val list = List(1, 2, 3, 4, "hello")
    // 先过滤,再map
    println(list.filter(f1).map(f3).map(f2))
    //思路2-模式匹配
    //小结:虽然使用模式匹配比较简单,但是不够完美
    val list2 = list.map(addOne2)
    println("list2=" + list2)
  }
  //模式匹配
  def addOne2( i : Any ): Any = {
    i match {
      case x:Int => x + 1
      case _ =>
    }
  }

  def f1(n: Any): Boolean = {
    n.isInstanceOf[Int]
  }

  def f2(n: Int): Int = {
    n + 1
  }
  //将Any->Int [map]
  def f3(n: Any): Int = {
    n.asInstanceOf[Int]
  }
}

偏函数快速入门
使用偏函数解决前面的问题,【代码演示+说明】

object PartialFunDemo02 {
  def main(args: Array[String]): Unit = {
    //使用偏函数解决
    val list = List(1, 2, 3, 4, "hello")
    //定义一个偏函数
    //1. PartialFunction[Any,Int] 表示偏函数接收的参数类型是Any,返回类型是Int
    //2. isDefinedAt(x: Any) 如果返回true ,就会去调用 apply 构建对象实例,如果是false,过滤
    //3. apply 构造器 ,对传入的值 + 1,并返回(新的集合)
    val partialFun = new PartialFunction[Any,Int] {

      override def isDefinedAt(x: Any) = {
        println("x=" + x)
        x.isInstanceOf[Int]
      }
      override def apply(v1: Any) = {
        println("v1=" + v1)
        v1.asInstanceOf[Int] + 1
      }
    }
    //使用偏函数
    //说明:如果是使用偏函数,则不能使用map,应该使用collect
    //说明一下偏函数的执行流程
    //1. 遍历list所有元素
    //2. 然后调用 val element = if(partialFun-isDefinedAt(list单个元素)) {partialFun-apply(list单个元素) }
    //3. 每得到一个 element,放入到新的集合,最后返回
    val list2 = list.collect(partialFun)
    println("list2" + list2)
  }
}

偏函数的小结

使用构建特质的实现类(使用的方式是PartialFunction的匿名子类)
PartialFunction 是个特质(看源码)
构建偏函数时,参数形式 [Any, Int]是泛型,第一个表示参数类型,第二个表示返回参数
当使用偏函数时,会遍历集合的所有元素,编译器执行流程时先执行isDefinedAt()如果为true ,就会执行 apply, 构建一个新的Int 对象返回
执行isDefinedAt() 为false 就过滤掉这个元素,即不构建新的Int对象.
map函数不支持偏函数,因为map底层的机制就是所有循环遍历,无法过滤处理原来集合的元素
collect函数支持偏函数

偏函数的简写形式

object PartialFun03 {
  def main(args: Array[String]): Unit = {

    //可以将前面的案例的偏函数简写
    def partialFun2: PartialFunction[Any,Int] = {
      //简写成case 语句
      case i:Int => i + 1
      case j:Double => (j * 2).toInt
    }

    val list = List(1, 2, 3, 4, 1.2, 2.4, 1.9f, "hello")
    val list2 = list.collect(partialFun2)
    println("list2=" + list2)

    //第二种简写形式
    val list3 = list.collect{
      case i:Int => i + 1
      case j:Double => (j * 2).toInt
      case k:Float => (k * 3).toInt
    }
    println("list3=" + list3) 

  }
}

运行结果

list2=List(2, 3, 4, 5, 2, 4)
list3=List(2, 3, 4, 5, 2, 4, 5)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值