Scala 高阶函数(二)
一、scala自带高阶函数
概述:可以接收一个函数的函数就是高阶函数,又称为算子
1。map:
将集合中的每一个元素通过指定功能(函数)映射(转换)成新的结果集
val list1 = List(1,2,3)
val list2 = list1.map(v=>v*2)
println(list2) //List(2, 4, 6)
2.flatten
介绍:flat即压扁,压平,扁平化。效果就是将集合中的每个元素的子元素映射到某个函数并返回新的集合
var list = List(List(1,2,3),List(3,4,5))
val list2 = list.flatten
println(list2) // 输出结果:List(1, 2, 3, 3, 4, 5)
val list3 = List(Array("zhangsan","lisi"),Array("lisi","wangwu"))
println(list3.flatten)
3.flatMap
介绍:先执行map,在执行flatten
var list = List("zhangsan lisi","lisi wangwu","wangwu wangwu")
val list2 = list.flatMap(v=>v.split(" "))
println(list2) //输出:List(zhangsan, lisi, lisi, wangwu, wangwu, wangwu)
4.filter (过滤器)
介绍:将符合要求的数据,通过指定函数的筛选放置到新的集合中
需求:将集合中首字母为‘A’的筛选到新的集合
var list = List("Alice","Tom","Jack","Abc")
val list2 = list.filter(v => {
v.startsWith("A")
})
println(list2) //输出结果:List(Alice, Abc)
5.reduce
介绍:对集合中的元素进行归约操作
需求:计算List集合中所有元素的和
var list = List(1,2,6,8)
val i: Int = list.reduce((v1,v2)=>v1+v2)
println(i)
6.fold
介绍:fold函数将上一步返回的值作为函数的第一个参数继续传递参与运算
需求: 计算List集合中所有元素的和
var list = List(1,2,6,8)
val i: Int = list.fold(5)((v1, v2) => {
v1 + v2
})
println(i)
上述代码等同于
list(5,1,2,6,8).reduce((v1, v2) => {
v1 + v2
})
7.sorted
介绍:对集合中的元素进行排序
var list = List(1,13,4,34)
println(list.sorted) //输出结果 List(1, 4, 13, 34)
println(list.sorted.reverse) //输出结果 List(34, 13, 4, 1)
8.sortBy
介绍:对集合中元组的某个元素进行排序
//List集合中存储一个学生的信息,分别是姓名和语文成绩,请按照语文成绩排序
var list = List(("张三",100),("李四",84),("王五",95),("赵六",30))
println(list.sortBy(t => t._2)) //List((赵六,30), (李四,84), (王五,95), (张三,100))
println(list.sortBy(t => t._2).reverse) //List((张三,100), (王五,95), (李四,84), (赵六,30)
//List集合中存储一个学生的信息,分别是姓名和语文成绩、数学成绩
//请按照语文成绩先排序,语文成绩相等者,按照数学成绩排序
var list2 = List(("张三",100,58),("李四",84,96),("王五",84,75),("赵六",30,61))
println(list2.sortBy(v => (v._2, v._3))(Ordering.Tuple2(Ordering.Int,Ordering.Int.reverse)))
//输出结果:List((赵六,30,61), (李四,84,96), (王五,84,75), (张三,100,58))
9.groupBy
介绍:根据集合中包含元组进行分组
var list = List(("张三",100),("张三",96),("李四",84),("李四",30))
//.groupBy(v=>v._1) 作用:根据遍历集合获取元组的第一个元素进行分组
val map: Map[String, List[(String, Int)]] = list.groupBy(v=>v._1)
println(map)
10.foreach
介绍:遍历集合中的元素
var list = List("张三","李四","王五")list.foreach(v=>{
println(v)
})
11.关于高阶函数的形参(匿名函数)的写法
val list = List(1,2,3)
1.正常的写法
list.map( (v:Int) => v*2 )
2.如果可以正常推断出匿名函数的形参类型,则:Int可以省略
list.map( (v) => v*2 )
3.如果匿名函数的形参个数只有1个,则()小括号可以省略
list.map( v => v*2 )
list.reduce( (v1,v2) => v1+v2 ) //此处(v1,v2)对应的小括号不能省略
4.如果匿名函数的形参(每一个),在匿名函数的代码体中只出现一次,则可以将形参列表和=> 省略,并且在函数体中使用_代表形参
list.map( v => v*2 ) 对应简写 list.map( _*2 )
list.map( v => v*v ) 不能使用_简写
list.reduce( (v1,v2) => v1+v2 ) 对应简写 list.reduce( _+_ )
二、高级函数
1.闭包
闭包是一个函数,返回值依赖于声明在函数外部的一个或多个变量。
闭包通常来讲可以简单的认为是可以访问一个函数里面局部变量的另外一个函数
介绍: 闭包就是一个函数和与其相关的引用环境组合的一个整体
def minus(x:Int)= (y:Int)=> x-y
val f1 = minus(20) //此处的f1就是闭包
f1(1) //输出19
f1(2) //输出18
详解:
① (y:Int)=> x-y
代表minus这个函数的返回值是一个匿名函数,那么将来这个匿名函数执行时就需要引入外部环境变量x
这就形成了闭包
② 当多次调用f(可以理解多次调用闭包) 发现使用的是同一个x,所以x不变
③ 在使用闭包时,主要搞清楚返回函数引用了函数外的哪些变量,因为他们会组合成一个整体
2.函数柯里化
介绍:函数编程中,接受多个参数的函数都可以转化为接收单个参数的函数,这个转化过程就叫柯里化
柯里化就是证明了函数只需要一个参数而已,不用设立柯里化存在的意义这样的命题。柯里化就是以函数为主体这种思想发展的必然产生结果
需求:编写一个函数,接收两个整数,可以返回两个数的乘积
//常规方式完成
def test1(v1:Int,v2:Int)={
v1+v2
}
test1(10, 20)
//闭包
def test2(x:Int)= (y:Int)=>x+y
test2(10)(20)
//柯里化
def test3(x:Int)(y:Int)={
x+y
}
test3(10)(20)