Scala入门系列之十二--高阶函数

传送门
Scala入门系列之一--使用命令行往文件输入数据并读取数据
Scala入门系列之二--数组、元组、列表、集合数据类型简述
Scala入门系列之三--类和方法的创建以及命令行执行scala文件
Scala入门系列之四--类成员的可见性(private)以及用value和value_=进行读取和修改
Scala入门系列之五--主构造器和辅助构造器
Scala入门系列之六--伴生对象和伴生类
Scala入门系列之七--scala中的继承
Scala入门系列之八--scala中的特质(trait),也称接口
Scala入门系列之九--模式匹配两大法宝(match语句和case类)
Scala入门系列之十--包
Scala入门系列之十一--函数式编程基础
Scala入门系列之十二--高阶函数
Scala入门系列之十三--针对容器的操作(遍历/映射/过滤/规约操作)
Scala入门系列之十四--使用IDEA编写Scala代码并Maven打包提交集群运行
传送门

一、高阶函数

1)概念简述:

高阶函数:当一个函数包含其它函数作为其参数或者返回结果为一个函数时,该函数被称为高阶函数

//典例:假设需要分别计算从一个整数到另一个整数的“连加和”、“平方和”以及“2的幂次和”

//方案一:不采用高阶函数
def sumInts(a:Int,b:Int):Int={
    if(a > b) 0 else a + sumInts(a+1,b)
}

def sumSquares(a:Int,b:Int):Int={
    if(a > b) 0 else a*a + sumSquares(a+1,b)
}
//2的幂次和 
def powerOfTwo(x:Int):Int = { if(x == 0) 1 else 2 * powerOfTwo(x - 1) }
def sumPowerOfTwo(a:Int,b:Int):Int={
    if(a > b) 0 else powerOfTwo(a) + sumPowersOfTwo(a+1,b)
}


//方案二:采用高阶函数
def sum(f:Int=>Int,a:Int,b:Int):Int = {
    if(a>b) 0 else f(a) + sum(f,a+1,b)
}

scala> sum(x=>x,1,5) //直接传入一个匿名函数
//且省略了参数x的类型,因为可以由sum的参数类型推断出来
res8: Int = 15
scala> sum(x=>x*x,1,5) //直接传入另一个匿名函数
res9: Int = 55
scala> sum(powerOfTwo,1,5) //传入一个已经定义好的方法
res10: Int = 62

2)练习:

采用高阶函数实现两个数的加减乘除操作,并打印结果

def sum(f:(Int,Int)=>Int,a:Int,b:Int){ f(a,b) }
sum(x,y=>x+y,2,3)
sum(x,y=>x-y,2,3)
sum(x,y=>x*y,2,3)
sum(x,y=>x/y,2,3)

3)提升:

与前面函数式编程基础结合

val list  = List(1, 2, 3, 4, 5, 6, 7, 8)
val lists = List(List(1, 2), List(3, 4), List(5, 6), List(7, 8))

// map
// result: List(2, 3, 4, 5, 6, 7, 8, 9)
list.map((x: Int) => x + 1) // 传入一个匿名函数, 接收每个值+1
list.map((x) => x + 1)      // 自动类型推导
list.map(x => x + 1)        // 只有一个参数可以去掉括号
list.map(_ + 1)             // 使用_占位符表示每一个值

// flatMap: flatten + map
lists.flatten               // List(1, 2, 3, 4, 5, 6, 7, 8)
lists.map(_.map(_ + 1))     // List(List(2, 3), List(4, 5), List(6, 7), List(8, 9))
lists.flatMap(_.map(_ + 1)) // List(2, 3, 4, 5, 6, 7, 8, 9)

// filter
list.filter(n => n > 5).foreach(println) // 6,7,8

// reduce
list.reduce(_ + _)          // 36
list.reduceLeft(_ + _)      // 36
list.reduceRight(_ + _)     // 36
list.reduce(_ - _)          // -34
list.reduceLeft(_ - _)      // -34  从左边开始, 左边减右边, 1-2, (1-2)-3, (1-2-3)-4, ...
list.reduceRight(_ - _)     // -4   从右边开始, 左边减右边, 7-8, 6-(7-8), 5-(6-7-8), ...

// fold: 同reduce提供一个初始值, foldLeft提供的初始值在最左, foldRight提供的初始值在最右
list.fold(10)(_ + _)          // 46
list.foldLeft(10)(_ + _)      // 46
list.foldRight(10)(_ + _)     // 46
list.fold(10)(_ - _)          // -26
list.foldLeft(10)(_ - _)      // -26  从左边开始, 左边减右边, 10-1, (10-1)-2, ...
list.foldRight(10)(_ - _)     // -6   从右边开始, 左边减右边, 10, ...

你可能感兴趣的:(Scala入门系列之十二--高阶函数)