0.Scala函数式编程
我们将来使用Spark/Flink的大量业务代码都会使用到函数式编程。下面这些事开发中常用的函数式编程。注意这些函数都是操作 Scala 集合的,一般会进行两类操作:转换操作(transformation )和行动操作(actions)(有些人喜欢叫他为聚合操作)。第一种操作类型将集合转换为另一个集合,第二种操作类型返回某些类型的值。
- 遍历( foreach )
- 映射( map )
- 映射扁平化( flatmap )
- 过滤( filter )
- 是否存在( exists )
- 排序( sorted 、 sortBy 、 sortWith )
- 分组( groupBy )
- 聚合计算( reduce )
- 折叠( fold )
1. foreach的使用详解
学习过了使用for表达式来遍历集合。发现scala的函数式编程,使用 foreach 方法来进行遍历、迭代。它可以让代码更加简洁。
【1.1语法结构】
foreach(f: (A) ⇒ Unit): Unit
【尖叫提示】
- 1.注意注意注意:foreach传入的参数是一个函数,匿名函数,只要是函数都可以传入进去
- 2.将调用foreach的集合中每个元素传给函数去执行,注意函数返回值是Unit。
【1.2foreach的执行过程】
【1.3foreach的使用演示】
//foreach是集合调用的,传入的参数是一个函数,函数调用集合中每个元素去执行。
val c= Array(1,2,3,4,5)
c.foreach((x:Int)=>{
println(x+1);
println(x*x)
})
//其中函数x的类型就是集合元素的类型
c.foreach((x:Int)=>println(x))
//2.注意这里函数,foreach没有返回值,或者说返回值只有Unit。
scala> val numbers = Seq(3, 7, 2, 9, 6, 5, 1, 4, 2)
numbers: Seq[Int] = List(3, 7, 2, 9, 6, 5, 1, 4, 2)
scala> numbers.foreach(x=>x>5)
scala> println(numbers.foreach(x=>x>5)) //注意这里同样函数,foreach没有返回值,或者说是Unit。
()
scala>numbers.foreach(x=>{
if( x>5) println(x)
})
9
6
scala> numbers.foreach(x=>{
if( x>5) x
})
【1.4简化foreach的使用】
1.4.1 使用类型推断简化函数定义
上述案例foreach传入的函数是标准函数,其实有更简洁的写法。因为使用foreach去迭代列表,而列表中的每个元素类型是确定的。所以scala可以自动来推断出来集合中每个元素参数的类型,创建函数时,可以省略其参数列表的类型。
val f = List(1,2,3,4,5,6)
f.foreach(x=>print(" "+x))
结果: 1 2 3 4 5 6
//注意,虽然List可以定义传入任何数据类型,其类型就会是Any,照样可以类型推断
scala> val g = List(1,2,3,4,"abc",3.13)
g: List[Any] = List(1, 2, 3, 4, abc, 3.13)
scala> g.foreach(x=>print(" "+x))
1 2 3 4 abc 3.13
1.4.2 使用下划线来简化函数定义
使用条件:当函数参数,只在函数体中出现一次,而且函数体没有嵌套调用时,可以使用下划线来简化函数定义
- 如果方法参数是函数,如果出现了下划线,scala编译器会自动将代码封装到一个函数中
- 参数列表也是由scala编译器自动处理
scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)
a.foreach(println(_))
1
2
3
4
2.forall的使用:对集合条件检查
foreach只要是为了对参数进行作用:比如 names.foreach{name=>println(name)}
有一个场景大家都知道,即确保集合中所有元素都要符合某些要求,如果有哪怕一个元素不符合条件,就需要进行一些处理,这个时候就需要用到forall了。
scala> val numbers = Seq(3, 7, 2, 9, 6, 5, 1, 4, 2)
numbers: Seq[Int] = List(3, 7, 2, 9, 6, 5, 1, 4, 2)
scala> numbers.forall(x=>x>5) //所有的集合元素都大于5?,注意forall是有返回值的。
res1: Boolean = false
scala> numbers.foreach(x=>x>5)
scala> println(numbers.foreach(x=>x>5)) //注意这里同样函数,foreach没有返回值,或者说是Unit。
()