一、函数字面量
在Scala 中,函数的使用方式和其他数据类型的使用完全一样,也就是说可以像定义一个变量一样定义一个函数,函数也可以和变量一样有“值”,这个值称为函数字面量。函数字面量又称为lambda 表达式,使用=>符号定义,=>表示这个函数将符号左边的转换成符号右边的。
scala> var fun = (x:Int) => x + 1
fun: Int => Int = $$Lambda$1155/991428767@77aeba9b
scala> fun(5)
res7: Int = 6
(x:Int) => x + 1 就是函数字面量,=>左边是字面量的参数列表,=>右边是函数体。如果函数体操作一行,要用花括号括起来。
在函数的函数字面量可以使用“_”作为占位符,这个占位符可以用传入的参数代替,如上面的代码可以改写为:
scala> var fun = (_:Int) + 1
fun: Int => Int = $$Lambda$1096/923727115@2b877a54
scala> fun(5)
res0: Int = 6
一个下划线代表了一个输入参数,两个下划线指代两个参数:第一个下划线代表第一个参数,第二个下划线代表第二个。
scala> def add(x:Int, y:Int):Int = {return x + y}
add: (x: Int, y: Int)Int
scala> var fun = add(_,_)
fun: (Int, Int) => Int = $$Lambda$1134/2002903874@51f68849
scala> fun(4,5)
res1: Int = 9
二、高阶函数
函数字面量可以作为参数或返回值,接受函数字面量作为参数的函数称为高阶函数。比如前面遍历集合元素用到的foreach 函数,它使用一个函数参数,为集合中每个运算调用传入的函数。
高阶函数主要有两种:一种是将一个函数当做另外一个函数的参数(即函数参数);另外一种是返回值是函数的函数。
1.函数作为参数
函数作为参数和C 语言中的参数是指针(这个指针又指向一个函数)类似。函数作为参数其值不仅可以是函数名,也可以是lambda 表达式。
def add1(x : Int) = x + 1
def add2(add1:(Int)=>Int, x:Int){
println(add1(x))
}
add2 接收两个参数,第一个参数是函数名add1,第二个参数是整型变量x 并将add1(x)的运算结果打印出来,执行结果为:
scala> add2(add1, 5)
6
scala> add2({x=>x+1},5)
6
2.函数作为返回值
函数作为返回值相当于一个函数里定义了一个匿名函数,把最外层函数的参数赋给函数体内的匿名函数,匿名函数有自己的参数,当调用外层函数的时候返回一个中间函数,当再次调用中间函数的时候才会返回数据结果。
scala> def add2(y : Int) = (x: Int) => x * y
add2: (y: Int)Int => Int
scala> add2(4)
res21: Int => Int = $$Lambda$1247/1373579841@517bdce0
scala> res21(6)
res22: Int = 24(www.daowen.com)
也可以采用如下方式直接调用:
scala> add2(4)(6)
res23: Int = 24
三、Scala 中常用的高阶函数
scala 内置一些高阶函数,用于定义集合操作,常用的有map,flatmap,filter 和reduce。
1. map 函数
map 函数是Scala 集合最常用的一个函数,遍历集合中的元素并对每个元素调用函数
,最后产生一个结果集合。
scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala> val list2 = list.map(x => x +1)
list2: List[Int] = List(2, 3, 4, 5, 6)
scala> var arr = Array(1,2,3)
arr: Array[Int] = Array(1, 2, 3)
scala> arr.map(x=>x+1)
res: Array[Int] = Array(2, 3, 4)
上述示例将集合中每个元素执行了x=>x+1 操作,结果组成了一个新的集合返回。
2. flatMap 函数
flatMap 类似于map,不过flatMap 对每个输入都会返回一个集合而不是元素,然后将这些集合合并成一个新的集合,就是所谓的“先映射后扁平化”。
scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala> val list2 = list.flatMap(x => List(x+1))
list2: List[Int] = List(2, 3, 4, 5, 6)
上述示例将list 中每个元素执行x => List(x+1)得到元素值+1 组成一个新列表,最后将这5 个列表再合并成一个列表。
3. filter 函数
遍历集合所有元素,滤除掉使函数返回false 的元素。
scala> List("Hadoop","Scala","Spark", "HBase", "Hive").filter(_.length > 4)
res24: List[String] = List(Hadoop, Scala, Spark, HBase)
例1. 求出映射的value 值大于2 的。
scala> Map("1"->1,"2"->2,"3"->3).filter(_._2>2)
res25: scala.collection.immutable.Map[String,Int] = Map(3 -> 3)
filter 中第一个下划线表示占位符,代表map 中的一个元素,如("1", 1),("2", 2),("3", 4),第二个参数_2 表示求出元组中第二个元素的值。
4. reduce
reduce 接收两个参数,首先将集合中的两个参数传入,得到的返回值作为第一个参数和另一个元素作为第二个参数再次传入,直到处理完整个集合。
scala> Array(1,2,4,3,5).reduce(_+_)
res26: Int = 15
scala> Array(1,2,4,3,5).reduce((x,y)=>x+y)
res27: Int = 15
上述示例使用reduce 实现了集合求值,实际上reduce 并不保证遍历的顺序,若要求特定顺序可以使用reduceLeft(从集合的头部开始操作)或reduceRight(从集合的尾部操作)。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。