Scala 函数式编程

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)(_*_))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值