简介
高阶函数(Higher-Order Function)就是操作其他函数的函数。Scala 中允许使用高阶函数, 高阶函数可以使用其他函数作为参数,或者使用函数作为输出结果。
简单实例
函数参数
object Test {
def main(args: Array[String]) {
println( apply( layout, 10) )
}
// 函数 f 和 值 v 作为参数,而函数 f 又调用了参数 v
def apply(f: Int => String, v: Int) = f(v)
def layout[A](x: A) = "[" + x.toString() + "]"
}
函数作为返回值
object Test {
def main(args: Array[String]) {
val x=multiplyBy(10)
println( x(50) )
}
def multiplyBy(factor:Double)=(x:Double) => factor*x
}
常用高阶函数
map函数
所有集合类型都存在map函数
Array类型
//这里面采用的是匿名函数的形式,字符串*n得到的是重复的n个字符串,这是scala中String操作的一个特点
scala> Array("spark","hive","hadoop").map((x:String)=>x*2)
res3: Array[String] = Array(sparkspark, hivehive, hadoophadoop)
//在函数与闭包那一小节,我们提到,上面的代码还可以简化
//省略匿名函数参数类型
scala> Array("spark","hive","hadoop").map((x)=>x*2)
res4: Array[String] = Array(sparkspark, hivehive, hadoophadoop)
//单个参数,还可以省去括号
scala> Array("spark","hive","hadoop").map(x=>x*2)
res5: Array[String] = Array(sparkspark, hivehive, hadoophadoop)
//参数在右边只出现一次的话,还可以用占位符的表示方式
scala> Array("spark","hive","hadoop").map(_*2)
res6: Array[String] = Array(sparkspark, hivehive, hadoophadoop)
List类型
scala> val list=List("Spark"->1,"hive"->2,"hadoop"->2)
list: List[(String, Int)] = List((Spark,1), (hive,2), (hadoop,2))
//写法1
scala> list.map(x=>x._1)
res20: List[String] = List(Spark, hive, hadoop)
//写法2
scala> list.map(_._1)
res21: List[String] = List(Spark, hive, hadoop)
scala> list.map(_._2)
res22: List[Int] = List(1, 2, 2)
Map类型
//写法1
scala> Map("spark"->1,"hive"->2,"hadoop"->3).map(_._1)
res23: scala.collection.immutable.Iterable[String] = List(spark, hive, hadoop)
scala> Map("spark"->1,"hive"->2,"hadoop"->3).map(_._2)
res24: scala.collection.immutable.Iterable[Int] = List(1, 2, 3)
//写法2
scala> Map("spark"->1,"hive"->2,"hadoop"->3).map(x=>x._2)
res25: scala.collection.immutable.Iterable[Int] = List(1, 2, 3)
scala> Map("spark"->1,"hive"->2,"hadoop"->3).map(x=>x._1)
res26: scala.collection.immutable.Iterable[String] = List(spark, hive, hadoop)
flatMap函数
//写法1
scala> List(List(1,2,3),List(2,3,4)).flatMap(x=>x)
res40: List[Int] = List(1, 2, 3, 2, 3, 4)
//写法2
scala> List(List(1,2,3),List(2,3,4)).flatMap(x=>x.map(y=>y))
res41: List[Int] = List(1, 2, 3, 2, 3, 4)
filter函数
scala> Array(1,2,4,3,5).filter(_>3)
res48: Array[Int] = Array(4, 5)
scala> List("List","Set","Array").filter(_.length>3)
res49: List[String] = List(List, Array)
scala> Map("List"->3,"Set"->5,"Array"->7).filter(_._2>3)
res50: scala.collection.immutable.Map[String,Int] = Map(Set -> 5, Array -> 7)
reduce函数
//写法1
scala> Array(1,2,4,3,5).reduce(_+_)
res51: Int = 15
scala> List("Spark","Hive","Hadoop").reduce(_+_)
res52: String = SparkHiveHadoop
//写法2
scala> Array(1,2,4,3,5).reduce((x:Int,y:Int)=>{println(x,y);x+y})
(1,2)
(3,4)
(7,3)
(10,5)
res60: Int = 15
scala> Array(1,2,4,3,5).reduceLeft((x:Int,y:Int)=>{println(x,y);x+y})
(1,2)
(3,4)
(7,3)
(10,5)
res61: Int = 15
scala> Array(1,2,4,3,5).reduceRight((x:Int,y:Int)=>{println(x,y);x+y})
(3,5)
(4,8)
(2,12)
(1,14)
res62: Int = 15
fold函数
scala> Array(1,2,4,3,5).foldLeft(0)((x:Int,y:Int)=>{println(x,y);x+y})
(0,1)
(1,2)
(3,4)
(7,3)
(10,5)
res66: Int = 15
scala> Array(1,2,4,3,5).foldRight(0)((x:Int,y:Int)=>{println(x,y);x+y})
(5,0)
(3,5)
(4,8)
(2,12)
(1,14)
res67: Int = 15
scala> Array(1,2,4,3,5).foldLeft(0)(_+_)
res68: Int = 15
scala> Array(1,2,4,3,5).foldRight(10)(_+_)
res69: Int = 25
// /:相当于foldLeft
scala> (0 /: Array(1,2,4,3,5)) (_+_)
res70: Int = 15
scala> (0 /: Array(1,2,4,3,5)) ((x:Int,y:Int)=>{println(x,y);x+y})
(0,1)
(1,2)
(3,4)
(7,3)
(10,5)
res72: Int = 15
函数柯里化
scala> def multiplyBy(factor:Double)=(x:Double)=>factor*x
multiplyBy: (factor: Double)Double => Double
//这是高阶函数调用的另外一种形式
scala> multiplyBy(10)(50)
res77: Double = 500.0
部分应用函数
部分应用函数指的是,函数有多个参数,而使用该函数时不提供所有参数(假设函数有3个函数),只提供0~2个参数。
//定义一个求和函数
scala> def sum(x:Int,y:Int,z:Int)=x+y+z
sum: (x: Int, y: Int, z: Int)Int
//不指定任何参数的部分应用函数
scala> val s1=sum _
s1: (Int, Int, Int) => Int = <function3>
scala> s1(1,2,3)
res91: Int = 6
//指定两个参数的部分应用函数
scala> val s2=sum(1,_:Int,3)
s2: Int => Int = <function1>
scala> s2(2)
res92: Int = 6
//指定一个参数的部分应用函数
scala> val s3=sum(1,_:Int,_:Int)
s3: (Int, Int) => Int = <function2>
scala> s3(2,3)
res93: Int = 6
//定义multiplyBy函数的部分应用函数,它返回的是一个函数
scala> val m=multiplyBy(10)_
m: Double => Double = <function1>
scala> m(50)
res94: Double = 500.0
注:下划线_并不是占位符的作用,而是作为部分应用函数的定义符。
忠于技术,热爱分享。欢迎关注公众号:java大数据编程,了解更多技术内容。