Scala combines object-oriented and functional programming in one concise, high-level language.
这是Scala官网介绍scala的第一句话,可以发现Scala的两大利器:更加纯粹的面向对象和函数式编程。
如果说面向对象让构造大型系统更加便捷,那么函数式编程则会让功能的实现更加快速,极大的提高编程效率。
高阶函数是指参数是函数,Scala主要应用是各种算子;或者返回的是函数,Scala中主要应用是柯里化。
一:常用算子
val list = List(4, 5, 6, 1, 2, 3)
1. map
// map用于对集合中的所有元素进行操作,eg 所有元素*2
val list1 = list.map(_ * 2)
list1: List[Int] = List(8, 10, 12, 2, 4, 6)
2. filter
// filter 用于过滤符合特定条件的元素,eg 只留下偶数
val list2 = list.filter(_ % 2 == 0)
list2: List[Int] = List(4, 6, 2)
3. sorted
// 排序
val list3 = list.sorted
list3: List[Int] = List(1, 2, 3, 4, 5, 6)
4. reverse
// 反转
val list4 = list3.reverse
list4: List[Int] = List(6, 5, 4, 3, 2, 1)
5. grouped
// 分组, eg 2个一组分组
val list5 = list.grouped(2)
ArrayBuffer(List(4, 5), List(6, 1), List(2, 3))
list5: Iterator[List[Int]] = <iterator>
6. flatten
// 压平,用于将多个集合压成一个
val list6 = list5.flatten
ArrayBuffer(4, 5, 6, 1, 2, 3)
list6: Iterator[Int] = <iterator>
7. flattenMap
// flatten 和 map 的整合
val list7 = List("stay foolish", "stay hungry")
val list8 = list7.flatMap(_.split(" "))
list8: List[String] = List(stay, foolish, stay, hungry)
8. reduce
// 规约操作 (((((4+5)+6)+1)+2)+3)
// 两个_依次被填补集合中的数值
val v9 = list.reduce(_ + _)
list9: Int = 21
9. fold
// 折叠, 第一个参数事初始值,注意并行情况下,可能会随着使用线程数量的不同出现不同的值
val v10 = list.fold(0)(_ + _)
v10: Int = 21
val v11 = list.par.fold(10)(_ + _)
10. aggregate
// 聚合,第一个参数事初始值,第二个入参包含两个函数,第一个是实现局部(各自分区)聚合的函数,第二个是整体聚合的函数
// _ + _.sum 的第一个 _ 表示初始值,第二个_代表子List。第二个函数和reduce,fold 一样
val v11 = list5.aggregate(0)(_ + _.sum, _ + _)
v11: Int = 21
11. 实践:wordCount
object a {
def main(args: Array[String]): Unit = {
val text = "welcome to zhanhtTect blog, stay Hungary, stay Foolish"
// 拿到单词
val words = text.split(",").flatMap(_.trim.split(" "))
// 单词计数1
val wordNum = words.map((_, 1))
// 按照单词进行聚合
val sum = wordNum.groupBy(_._1)
val result = sum.mapValues(_.size)
print(result)
}
}
二:柯里化
柯里化指将接受多个参数的函数转换为接受一个参数,它可以帮助类型推断,提高方法的效率。
// 普通sum函数
def sum(a : Int, b : Int) = a + b
// Currying sum 写法1
def curringSum1(a : Int)(b : Int) = a + b
// Currying sum 写法2
// 这种写法也能直观的表明,柯里化实现过程起始是掉用两次普通函数
// 第一次使用第一个参数,返回一个单参数的函数,在使用第二个参数,返回最终结果
def curringSum2(a : Int) = (b : Int) => a + b