1. 函数定义
1.1 函数字面量
函数字面量可以体现函数式编程的核心理念。在函数式编程中,函数的使用方式和其他数据类型的使用方式完全一致,可以被传递和操作(可以像定义变量那样去定义一个函数)。这时,函数的“类型”和“值”成为两个分开的概念,其中,函数的“值”就是“函数的字面量”。
1.2 函数的类型和值
def counter(value: Int): Int = {value}
val counter: Int => Int = {(value) => value+=1}
// 第一个Int是参数类型;第二个Int是返回值类型。
函数类型:(Int) => Int
只有一个参数时,括号可以省略,Int => Int。
函数值: (value) => {value} // 只有一条语句时,{}也是可以省略的。
def f1(x: Int) = x + 3
val f2 = (x: Int) => x + 3
println(f2(4))
1.3 匿名函数
Lambda表达式
(num: Int) => num * 2
// 一个参数情况下,括号可以省略
num: Int => num * 2
定义函数变量
val f: Int=>Int = (num: Int) => num*2
print(f(100))
或
scala> val f = (num: Int) => num*2
f: Int => Int = <function1>
或
scala> val f: Int=>Int = (num) => num*2
f: Int => Int = <function1>
1.4 闭包
闭包是一种比较特殊的函数,反映了一个从开放到封闭的过程。
var more = 10
val add_new = (x: Int) => x+more
println(add_new(3)) // 13
more = 100
println(add_new(3)) // 103
其中闭包函数中的more是自由变量,可以在其他处定义。每次调用时都会创建一个新闭包(每个闭包都会访问当前活跃的more)。
1.5 占位符语法
为了让函数字面量更加简洁,可以使用下划线作为一个或多个参数的占位符,只要每个参数在函数字面量内仅出现一次。
var list = List(-3, -5, 1)
list.filter(x=>x>0).foreach(println)
list.filter(_>0).foreach(println)
val f = (_: Int) + (_: Int)
println(f(2, 3))
2. 集合操作
2.1 集合遍历
2.1.1 列表遍历
val list = List(1, 2, 3)
// 方法1:
for(e <- list) println(e)
// 方法2:
list.foreach(println)
// 方法3:
list.foreach(println(_))
// 方法4:
list.foreach(e => println(e))
2.1.2 map遍历
val map = Map("one"->1, "two"->2, "three"->3)
// 方法1:
for((k,v) <- map) println(k + ": " + v)
// 方法2:
for(kv <- map) println(kv._1 + ": " + kv._2)
// 方法3:
map.foreach({
case(k,v) => println(k + ": " + v)
})
// 方法4:
map foreach {
case(k,v) => println(k + ": " + v)
}
2.2 map()
val list = List("one", "two", "three")
// list.map(s => s.toUpperCase).foreach(println)
list.map(_.toUpperCase()).foreach(println)
2.3 flatMap()
在flatMap中,我们会传入一个函数,这个函数会对每个输入都返回一个集合(而不是一个元素),然后,flatMap 把生成的多个集合“拍扁”成为一个集合。
val list = List("one", "two", "three")
println(list.flatMap(_.toList))
// List(o, n, e, t, w, o, t, h, r, e, e)
2.4 filter()
map
val map = Map("one"->"beijing", "two"->"nanjing", "three"->"nanning")
val res1 = map filter {kv => kv._2 contains "jing"}
println(res1)
// Map(one -> beijing, two -> nanjing)
// val res2 = map.filter({kv => kv._2.startsWith("nan")})
val res2 = map.filter(_._2.startsWith("nan"))
println(res2)
// Map(two -> nanjing, three -> nanning)
list
val map = List("beijing", "nanjing", "nanning")
val res = map.filter(_.startsWith("nan"))
// val res = map.filter({_.startsWith("nan")})
println(res)
// List(nanjing, nanning)
2.5 reduce()
对集合中的元素进行规约
val list = List(1, 2, 3, 4)
// 从头开始
println(list.reduceLeft(_+_))
// 从尾开始
println(list.reduceRight(_+_))
println(list.reduce(_+_))
2.6 fold()
折叠fold与规约类似,特殊之处是,它提供一个初始“种子”。
val list = List(1, 2, 3, 4)
println(list.fold(10)(_*_))
println(list.foldLeft(10)(_*_))
println(list.foldRight(10)(_*_))
706

被折叠的 条评论
为什么被折叠?



