scala函数式编程具体体现

1、Block块语句

object Demo04Block {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /*
      {} 块语句
      最后一个值或表达式作为块语句的返回值
     */
    val age = 20
    val info = if (age > 1) {
    
    
      println("块语句!!!")
      "hhhhhhh"
      1
    }

    println(info)
  }

}

2、yield 礼让,构建新集合

将遍历过程中处理的结果返回到一个新Vector集合中,使用yield关键字

object Demo01Yield {
    
    
  def main(args: Array[String]): Unit = {
    
    
    for (i <- 1 to 10){
    
    
      print(i)
    }
    println()
    println("************")

    //yield 礼让 可以构建一个新的集合
    val value = for (i <- 1 to 10) yield i * 10
    println(value)  // Vector(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)

    // ArrayBuffer是可变的数组
    val buffer = (for (i <- 1 to 10) yield i * 10).toBuffer
    println(buffer)  // ArrayBuffer(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
  }
}

3、scala函数式编程,函数与方法

在这里插入图片描述

object Demo03Function {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /*
      方法也称为函数
      函数没有 重写重载 的概念
      函数的几种写法
     */
    def sum(a: Int, b: Int): Int = {
    
    
      a + b
    }
    // 函数无法重载
    //    def sum(): Unit ={
    
    
    //
    //    }
    println(sum(5, 3))

    /* 无参无返回值 */
    def f1() = {
    
    

    }
    /* 有一个参数,无返回值 */
    def f2(a: Int) = {
    
    

    }
    /* 无参无返回值,写参数的小扩号和返回类型都可以省略不写 */
    def f3 = {
    
    
      println("简化版!!!")
    }
    /* 两个参数,有返回值 */
    def f4(name: String,age: Int): String = {
    
    
      s"$name   $age"
    }

    println(f4("zhangsan",18))
  }

}

class Test {
    
    
  /*
    类中的函数称为方法
    方法可以 重写 重载
   */
  def sum(a: Int, b: Int): Int = {
    
    
    a + b
  }

  def sum() = {
    
    

  }
}

4、函数参数分类及使用

(1)可变参数
(2)如果参数列表中存在多个参数,那么可变参数一般放置在最后
(3)参数默认值
(4)带名参数

object Demo05FuncParam {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /*
      函数参数的使用:
        默认参数  传名参数  可变参数
     */

    /* 调用下方的函数 */
    println(f1("zhangsan",18,"八达岭"))
    println(f1("函数的默认参数",20))

    println(f2("lisi",18,"宝泉"))
    println(f2(age = 22,name = "函数的传名参数",addr = "方特"))

    f3("秦始皇","赵匡胤","李世民","朱元璋")
    println()
    f3("虞姬","甄姬","蔡文姬")
    println()
    // 打印十遍字符串内容
    println("a"*10)

  }

  /* 创建函数的时候参数指定默认值,当调用的时候可以传值,如果不传使用默认的值 */
  def f1(name: String,age: Int,addr: String = "八大里"): String = {
    
    
    s"$name  $age  $addr"
  }

  /* 带名参数,传递参数的时候可以不按照参数的顺序,但是必须要带着参数的名称 */
  def f2(name: String,age: Int,addr: String): String = {
    
    
    s"$name  $age  $addr"
  }

  /* 可变参数,变长参数 参数的个数不确定 */
  def f3(name: String*) = {
    
    
    print("函数的可变参数:  ")
    for (a <- name){
    
    
      print(a + " ")
    }
  }

}

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

    /* 传值函数,传入的是函数的返回值 */
    sum(10,func01(100))
    println("-------------")
    /* 传名函数,传入的是函数名称,当被调用的时候出才执行 */
    sum1(10,func01)
  }

  def func01(num:Int): Int ={
    
    
    println("Num: "+num)
    num
  }


  //call by value: 传值函数,传入的是函数的返回值
  def sum(a:Int,b:Int): Unit ={
    
    
    println("开始计算求和")
    println(a+b)
  }


  //call by name: 传名函数,传入的是函数名称,当被调用的时候出才执行
  def sum1(a:Int,f:(Int)=>Int){
    
    
    val b = 100
    println("开始计算求和")
    println(a+f(b))
  }
}

5、函数至简原则

(1)return可以省略,Scala会使用函数体的最后一行代码作为返回值
(2)返回值类型如果能够推断出来,那么可以省略
(3)如果函数体只有一行代码,可以省略花括号
(4)如果函数无参,则可以省略小括号。若定义函数时省略小括号,则调用该函数时,也需省略小括号;若定时函数时未省略,则调用时,可省可不省。
(5)如果函数明确声明Unit,那么即使函数体中使用return关键字也不起作用
(6)Scala如果想要自动推断无返回值,可以省略等号
(7)如果不关心名称,只关系逻辑处理,那么函数名(def)可以省略
(8)如果函数明确使用return关键字,那么函数返回就不能使用自行推断了,需要声明返回值类型

6、高阶函数

定义:参数为函数的函数称为高阶函数

object Demo07Func {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /*
      把函数当做参数来传递
     */
    def sum1(a: Int,b: Int): Int = {
    
    
      return a + b
    }

    def sum2(a: Int,b: Int): Int = {
    
    
      return a * b
    }

    /* 第三个参数是函数 */
    def sum3(a: Int,b: Int,aaa:(Int,Int) => Int): Int = {
    
    
      return aaa(a,b)
    }

    println(sum3(3,3,sum1)) // 6
    println(sum3(3,3,sum2)) // 9
  }

}

7、匿名函数

没有名字的函数就是匿名函数,可以直接通过函数字面量(表达式)来设置匿名函数,函数字面量定义格式如下
在这里插入图片描述

object Demo08Func {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /*
      匿名函数
        val 函数名称 =(参数列表) => {函数体}
        var f1 = (a: Int,b: Int) => { a + b }
     */
    var f1 = (a: Int,b: Int) => {
    
    
      a + b
    }
    println("加了变量接收的匿名函数:  " + f1(1,1))

    /* 第三个参数是函数 */
    def f2(a: Int,b: Int,aaa:(Int,Int) => Int): Int = {
    
    
      aaa(a,b)
    }
    /* 调用,第三个参数直接输入一个匿名函数 */
    println(f2(3,3,f1)) // 6
    println(f2(3,3,(a: Int,b: Int) => a * b)) // 9

    println("************")
    /* 匿名函数的应用场景 */
    val array = Array(1, 2, 3, 4, 5, 6)
    
    array.map(i => i * 10).foreach(println(_)) // 10 20 30 40 50 60
    println("************")
    
    // _ 代表每一个元素
    array.map(_ * 10).foreach(println(_)) // 10 20 30 40 50 60
    println("************")
    
    def f3(num: Int): Int = {
    
    
      num * 10
    }
    array.map(f3).foreach(println(_)) // 10 20 30 40 50 60
  }

}

8、函数闭包

闭包:就是一个函数和与其相关的引用环境(变量)组合的一个整体(实体)

object Demo09ClosePackage {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /* 闭包  引入外部变量 */
    val num = 10

    def sum(a: Int): Int = {
    
    
      // 引入外部变量 num
      a + num
    }
    println("引入外部变量结果为: " + sum(10)) // 20
  }
}

9、函数柯理化

函数柯里化:将一个接收多个参数的函数转化成一个接受一个参数的函数过程,可以简单的理解为一种特殊的参数列表声明方式。

object Demo10Currying {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /* 这是两个参数的函数 */
    def sum(a: Int,b: Int): Int = {
    
    
      a + b
    }

    /*
      柯里化:将原来两个参数的函数拆分为以原来第一个参数为参数的函数
      返回的新的函数再以原来第二个参数为参数的函数
     */
    def sum1(a: Int)(b: Int): Int = {
    
    
      a + b
    }
    def sum2(a: Int)(b: Int)(c: Int): Int = {
    
    
      a + b + c
    }
    println(sum(10,20)) // 30
    println(sum1(10)(20)) // 30
    println(sum2(10)(20)(30)) // 60
  }
}

10、递归

一个函数/方法在函数/方法体内又调用了本身,我们称之为递归调用

object Demo11jiecheng {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /*
      阶乘运用递归思想
      所谓递归,直白的说就是自己调用自己
     */
    def test(num: Int): Int = {
    
    
      if (num == 1){
    
    
        num
      }else{
    
    
        num * test(num - 1)
      }
    }

    println(test(5)) // 120
  }
}

11、lazy 惰性求值,懒加载

当函数返回值被声明为lazy时,函数的执行将被推迟,直到我们首次对此取值,调用,该函数才会执行。这种函数我们称之为惰性函数。

import scala.io.Source

object Demo12lazy {
    
    
  def main(args: Array[String]): Unit = {
    
    
    /*
      懒加载
      只有被调用的时候才会执行
     */
    var age = 20
    println(age) // 20

    lazy val res = if (age > 18) {
    
    
      age = 100
      s"现在的 age is $age"
    }

    println("调用前age是: " + age) // 20
    /* 此时懒加载被调用了 */
    println(res) // 现在的 age is 100
    println("调用后的age是:  " + age) // 100

    /*
      懒加载应用场景:
        当在创建大的变量,或者执行比较耗时的程序  比如读写数据
     */
    val source = Source.fromFile("E:/快捷键.txt")
    val lines: Iterator[String] = source.getLines()
    for (line <- lines){
    
    
      println(line)
    }
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_46122692/article/details/109010917