匿名函数、函数作为返回值、List

object Demo09Func2 {
  /**
   * 面向函数(函数式编程、高阶函数)
   * 1、函数作为参数
   * 2、函数作为返回值
   *
   * 面向对象编程:将对象传来传去 对象可以作为函数的参数或返回值传来传去 注意有类型的约束
   * 面向函数编程:将函数传来传去 函数可以作为函数的参数或返回值传来传去 注意有类型的约束
   *
   * 如何描述函数的类型
   * 跟def无关
   * 跟方法名无关
   * 跟方法体无关
   * 跟参数的名称无关
   *
   * 函数的类型跟该函数“参数的类型、参数的个数、参数的顺序、返回值类型”有关
   * (参数,参数) => 返回值类型
   */

  //这是一个“参数只有一个类型String 返回值类型为Int”这样的函数
  //String=>Int
  def func1(str:String): Int ={
    str.toInt+100
  }

  //这是一个“参数只有一个类型String 返回值类型为Int”这样的函数
  //String=>Int
  def func2(str:String): Int ={
    str.toInt+200
  }

  //这是一个“参数只有一个类型Int 返回值类型为String”这样的函数
  // Int=>String
  def func3(int:Int): String ={
    int+300+""
  }

  //可以接收一个函数并进行调用
  //接收一个"String=>Int" 这样类型的
  def funcX(func:String=>Int) ={
    println(func("500"))
  }

  /**
   * 匿名函数(类似lambda表达式):没有名字的函数
   * (参数名:参数类型,参数名:参数类型,参数名:参数类型)=>{方法体}
   */
  (str:String)=>{str.toInt+200}
  //匿名函数也可以拥有名称
  val func4: String => Int = (str:String)=>{str.toInt+400}
  val func5: String => Int = (str)=>{str.toInt+500}

  def main(args: Array[String]): Unit = {
    funcX(func1)
    funcX(_.toInt+100)//用匿名函数替代
    funcX(func2)
    funcX(_.toInt+200)//用匿名函数代替func2的逻辑
    //funcX(func3) //func3不符合funcX的定义

    funcX(func4)
    
    /**
     * 匿名函数的简化
     * 1、如果代码只有一行 花括号可以省略
     * 2、如果匿名函数值为 参数 传入另外一个函数 则匿名函数的参数类型可以省略
     * 3、如果匿名函数只有一个参数则括号可以省略
     * 4、如果匿名函数中的参数在逻辑中只使用了一次 则可以用下划线代替 然后 => 左边的部分可以省略
     */
    funcX((str:String)=>{str.toInt+300})//太繁琐 很多东西可以省略
    funcX((str:String)=>str.toInt+300)
    funcX((str)=>str.toInt+300)
    funcX(str=>str.toInt+300)
    funcX(_.toInt+300)//可读性比较低
  }
}

600
600
700
700
900
800
800
800
800
800

object Demo10Func3 {
  //以函数作为参数 应用
  def main(args: Array[String]): Unit = {
    val arr: Array[Int] = Array[Int](1, 2, 3, 4, 5, 6, 7)
    //遍历数组
    /**
     * Java的思想
     * for(int i=0;i<arr.length;i++){
     * System.out.println(arr[i]);
     * }
     */
    //Scala的方式 类似Java中增强for(for—each)
    for (elem <- arr) {
      println(elem)
    }

    println("*"*20)

    /**
     * foreach方法可以接收一个函数f
     * 函数f的类型: Int=>U
     * Int:arr中的每一个元素的类型是 Int
     * U:相当于Unit 表示没有返回值
     *
     * println函数:Any => Unit
     */
    arr.foreach(println)//foreach 会将arr中的每一个元素作为参数 传给println方法

    println("*"*20)

    //将arr中的每个元素扩大一倍 并构建一个新的arr
    //用Java的思想做
    var count:Int=0
    val arr2: Array[Int] = new Array[Int](arr.length)
    while(count<arr.length){
      arr2(count)=arr(count)*2
      count+=1
    }
    //mkString 可以指定一个分隔符 将arr2中的每个元素与分隔符拼接 返回一个 字符串
    //类似Python中的join方法
    println(arr2.mkString(","))
    println("*"*20)

    //以函数式编程的思想来实现
    val arr3: Array[Int] = new Array[Int](arr.length)
    def extend1(int: Int): Unit ={
      println(int*2)
    }
    var count2:Int=0
    arr.foreach((elem:Int)=>{
      arr3(count2)=elem*2
      count2+=1
    })
    println(arr3.mkString("|"))
    println("*"*20)

    /**
     * map 方法也需要接收一个函数f:
     * 函数f:Int=>B
     * Int:arr中的每一个元素的类型是 Int
     * B:表示返回值类型由自己指定
     *
     * map 和 foreach最大的区别在于 有无返回值
     */
    val arr4: Array[Int] = arr.map((elem: Int) => {
      elem*2
    })
    println(arr4.mkString(","))
    println("*"*20)

    //简化
    println(arr.map((elem: Int) => {elem*2}).mkString("/"))
    println(arr.map((elem) => {elem*2}).mkString("/"))
    println(arr.map(elem => {elem*2}).mkString("/"))
    println(arr.map(elem => elem*2).mkString("/"))
    println(arr.map(_*2).mkString("/"))
    println("*"*20)

    println(arr.map(_*2).mkString("|"))
    println(arr.map(_*3).mkString("|"))
    println(arr.map(_*4).mkString("|"))
    println(arr.map(_*1.5).mkString("|"))
    println(arr.map(_*0.5).mkString("|"))
    println("*"*20)
  }
}

1
2
3
4
5
6
7
********************
1
2
3
4
5
6
7
********************
2,4,6,8,10,12,14
********************
2|4|6|8|10|12|14
********************
2,4,6,8,10,12,14
********************
2/4/6/8/10/12/14
2/4/6/8/10/12/14
2/4/6/8/10/12/14
2/4/6/8/10/12/14
2/4/6/8/10/12/14
********************
2|4|6|8|10|12|14
3|6|9|12|15|18|21
4|8|12|16|20|24|28
1.5|3.0|4.5|6.0|7.5|9.0|10.5
0.5|1.0|1.5|2.0|2.5|3.0|3.5
********************

object Demo11Func4 {
  //以函数作为返回值

  //将函数作为返回值时 返回值的类型得手动指定
  def func1(str1:String):String=>Int={
    println("func1被调用")
    //String => Int
    def func1_1(str2:String): Int ={
      println("func1_1被调用")
      str1.toInt+str2.toInt
    }
    func1_1
  }

  //简化定义
  //将函数作为返回值时 返回值的类型得手动指定
  //函数的柯里化:将有N个参数的函数变成N个只有一个参数的函数
  def func2(str1:String)(str2:String):Int={
      str1.toInt+str2.toInt
  }

  //不使用函数作为返回值
  def func3(str1:String,int:Int): Int={
    str1.toInt+int
  }

  //偏应用函数:将有N个参数函数 变成N-X个参数的函数 X表示已经固定的参数
  //计算a的b次方,如果不给定b,则计算a的三次方
  //第一种方式:使用默认参数
  def aPowerB(a:Int,b:Int=3): Unit ={
    println(Math.pow(a,b))
  }
  //第二种方式:使用函数式编程的思想
  def aPowerB2(a:Int)(b:Int): Unit ={
    println(Math.pow(b,a))
  }

  def main(args: Array[String]): Unit = {
    val func1_1: String => Int = func1("100")
    val i: Int = func1_1("200")
    println(i)
    //简化调用
    println(func1("100")("200"))
    println(func2("300")("400"))
    println(func3("500",600))

    aPowerB(2,2)
    aPowerB(2,3)
    aPowerB(2,4)
    aPowerB(2)

    //偏应用函数:将有N个参数函数 变成N-X个参数的函数 X表示已经固定的参数
    val aPower3: Int => Unit = aPowerB2(3)
    aPower3(2)
    aPower3(3)
    aPower3(4)

    aPowerB2(4)(2)
  }
}

 func1被调用
func1_1被调用
300
func1被调用
func1_1被调用
300
700
1100
4.0
8.0
16.0
8.0
8.0
27.0
64.0
16.0

object Demo12List {
  def main(args:Array[String]): Unit ={
    /**
     * List列表
     * 特点:元素可以重复、有序的、不可变的
     */
    //定义一个List
    val list1: List[Int] = List[Int](1, 2, 1, 2, 3, 5, 7, 3, 4, 6, 4, 9, 8)
    println(list1)

    //通过下标(index,索引)取元素
    println(list1(4))
    //list1(4)=10 //List不能修改

    //List中常用的方法
    println(list1.max)//最大值
    println(list1.min)//最小值
    println(list1.sum)//求和
    println(list1.head)//取第一个元素
    println(list1.tail)//取除第一个元素以外的元素
    println(list1.length)//长度 同size
    println(list1.take(3))//取前N个元素
    println(list1.distinct)//返回去重后结果
    println(list1.isEmpty)//判断是否为空
    println(list1.size)//大小 同length
    println(list1.reverse)//倒转List

    //List常见的操作
    /**
     * map 和 foreach
     * 区别:有无返回值
     * 都需要接收一个函数f
     * 都会将List中的每个元素传给函数f
     */
    //有返回值
    val newList1: List[Int] = list1.map(elem => elem * elem)
    println(newList1.mkString(","))

    //遍历
    list1.foreach(println)

    //过滤
    /**
     * filter方法:
     * 接收一个函数类型的参数p
     * p:Int=>Boolean
     * 函数p的参数类型为Int:因为list1中的每个元素的类型为Int
     * 函数p的返回值类型为Boolean
     * filter会根据函数p最后的返回值进行过滤
     * true: 保留数据
     * false: 将数据过滤
     */
    //将奇数过滤出来
    def filterList1(elem:Int): Boolean ={
      var flag:Boolean=false
     if(elem%2==1){
       flag=true
     }
      flag
    }

    //使用一般的函数
    val filterList: List[Int] = list1.filter(filterList1)
    println(filterList.mkString(","))

    //使用匿名函数
    val filterList2:List[Int]=list1.filter((elem:Int)=> {
      var flag: Boolean = false
      if (elem % 2 == 1) {
        flag=true
      }
      flag
    })
    println(filterList2.mkString(","))
    //简写
     println(list1.filter(elem => elem % 2==1).mkString(","))
    println(list1.filter(_%2==1).mkString(",")) //偶数
    println(list1.filter(_%2==0).mkString(",")) //奇数

    //groupBy 需要指定一个分组“字段”
    val zs: Stu = Stu("001", "zs", 20, "文科一班")
    val ls: Stu = Stu("002", "ls", 21, "文科二班")
    val ww: Stu = Stu("003", "ww", 22, "文科三班")
    val zl: Stu = Stu("004", "zl", 21, "理科二班")
    val lj: Stu = Stu("005", "lj", 20, "理科一班")

    val stuList: List[Stu] = List[Stu](zs, ls, ww, zl, lj)

    //按班级分组
    /**
     * 得到一个Map
     * Map的Key就是指定的分组“字段”表示每一组
     * Map的value就是经过分组过后属于同一组的元素一同构成的List
     */
    //    stuList.groupBy((stu:Stu)=>{stu.clazz})
    val groupStu: Map[String, List[Stu]] = stuList.groupBy(_.clazz)
    println(groupStu)
  }

  case class Stu(id:String,name:String,age:Int,clazz:String)
}

 List(1, 2, 1, 2, 3, 5, 7, 3, 4, 6, 4, 9, 8)
3
9
1
55
1
List(2, 1, 2, 3, 5, 7, 3, 4, 6, 4, 9, 8)
13
List(1, 2, 1)
List(1, 2, 3, 5, 7, 4, 6, 9, 8)
false
13
List(8, 9, 4, 6, 4, 3, 7, 5, 3, 2, 1, 2, 1)
1,4,1,4,9,25,49,9,16,36,16,81,64
1
2
1
2
3
5
7
3
4
6
4
9
8
1,1,3,5,7,3,9
1,1,3,5,7,3,9
1,1,3,5,7,3,9
1,1,3,5,7,3,9
2,2,4,6,4,8
Map(理科一班 -> List(Stu(005,lj,20,理科一班)), 理科二班 -> List(Stu(004,zl,21,理科二班)), 文科一班 -> List(Stu(001,zs,20,文科一班)), 文科二班 -> List(Stu(002,ls,21,文科二班)), 文科三班 -> List(Stu(003,ww,22,文科三班)))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值