zoukankan      html  css  js  c++  java
  • Scala 偏函数

    link

    提出一个需求,引起思考
    给你一个集合 val list = List(1, 2, 3, 4, "abc") ,请完成如下要求:
    1) 将集合 list 中的所有数字+1,并返回一个新的集合
    2) 要求忽略掉 非数字 的元素,即返回的 新的集合 形式为 (2, 3, 4, 5)
    解决方式-filter + map 返回新的集合, 

    解决方式-模式匹配

    package com.atguigu.chapter13
    
    /*
    给你一个集合 val list = List(1, 2, 3, 4, "abc") ,请完成如下要求: 将集合 list 中的所有数字+1,并返回一个新的集合
    要求忽略掉 非数字 的元素,即返回的 新的集合 形式为 (2, 3, 4, 5)
    */
    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]
      }
    }
    package com.atguigu.chapter13
    
    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)
        val list2 = list.collect(partialFun)
        println("list2 = " + list2)
      }
    }

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

    偏函数的简化版

    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) // (2,3,4,5)
      }
    }
    关注公众号 海量干货等你
  • 相关阅读:
    ural 1723 Sandro's Book
    ural 1104 Don’t Ask Woman about Her Age
    ural 1052 Rabbit Hunt
    ural 1837 Isenbaev's Number
    ural 1348 Goat in the Garden 2
    ural 1207 Median on the Plane
    ural 1640 Circle of Winter
    段错误 核心已转储尝试解决
    显卡相关命令介绍【转载】
    Linux的top命令学习【转载】
  • 原文地址:https://www.cnblogs.com/sowhat1412/p/12734162.html
Copyright © 2011-2022 走看看