map 函数
它将某个函数应用到集合中的每个元素,并产生一个结果集合。
我们可以这样对列表的元素进行平方:
scala
scala> list1
res3: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list1.map(x=>x*x)
res4: List[Int] = List(0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100)
flatten 函数
将嵌套结构扁平化为一个层次的集合
scala
scala> List(List(1, 2), List(3, 4)).flatten
res0: List[Int] = List(1, 2, 3, 4)
flatMap 函数
flatMap是map的一种扩展。在flatMap中,我们会传入一个函数,该函数对每个输入都会返回一个集合(而不是一个元素),然后,flatMap把生成的多个集合"拍扁"成为一个集合。
scala
scala> val list3 = 10 to 20 toList
list3: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
scala> val list2 = 1 to 10 toList
list2: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> val list4 = List(list2, list3)
list4: List[List[Int]] = List(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))
scala> list4.flatMap(x=>x.map(y=>y*2))
res2: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40)
注:flatMap并不一定用于元素是序列的列表,他只需要应用的函数返回的结果是GenTraversableOnce即可(列表的父类),例如:
scala
scala> List(1,2,3,4,5)
res0: List[Int] = List(1, 2, 3, 4, 5)
scala> res0.flatMap(x => 1 to x )
res1: List[Int] = List(1, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5)
flatMap还可以看作是flatten和map两种的结合
scala
scala> val nestedNumbers = List(List(1, 2), List(3, 4))
nestedNumbers: List[List[Int]] = List(List(1, 2), List(3, 4))
scala> nestedNumbers.flatMap(x => x.map(_ * 2))
res0: List[Int] = List(2, 4, 6, 8)
//等价于
scala> nestedNumbers.map((x: List[Int]) => x.map(_ * 2)).flatten
res1: List[Int] = List(2, 4, 6, 8)
由以上代码可以看出,flatMap是map和flatten操作的结合,先进行map操作,然后再进行flatten操作;flatMap还可以去除掉空元素NONE。
map VS flatMap
map函数的用法,顾名思义,将一个函数传入map中,然后利用传入的这个函数,将集合中的每个元素处理,并将处理后的结果返回。而flatMap与map唯一不一样的地方就是传入的函数在处理完后返回值必须是List,其实这也不难理解,既然是flatMap,那除了map以外必然还有flat的操作,所以需要返回值是List才能执行flat这一步。
例子:
scala
object collection_t1 {
def flatMap1(): Unit = {
val li = List(1,2,3)
val res = li.flatMap(x => x match {
case 3 => List('a','b')
case _ => List(x*2) //输出需要为 List
})
println(res)
}
def map1(): Unit = {
val li = List(1,2,3)
val res = li.map(x => x match {
case 3 => List('a','b')
case _ => x*2 // 输入不需要为 List
})
println(res)
}
def main(args: Array[String]): Unit = {
flatMap1()
map1()
}
}
输出为:
scala
List(2, 4, a, b)
List(2, 4, List(a, b))
特别的例子:
scala
scala> val books = List("Hadoop", "Hive", "HDFS")
books: List[String] = List(Hadoop, Hive, HDFS)
scala> books map (s => s.toList)
res3: List[List[Char]] = List(List(H, a, d, o, o, p), List(H, i, v, e), List(H, D, F, S))
scala> books flatMap (s => s.toList)
res2: List[Char] = List(H, a, d, o, o, p, H, i, v, e, H, D, F, S)
scala> books.map(s => s.toUpperCase)
res1: List[String] = List(HADOOP, HIVE, HDFS)
// flatMap函数的输出结果必须为List,然后才进行flatten,因此,需要将s.toUpperCase生成的 String
// 转为为List,如 "HADOOP".toList 变为 List[Char] = List(H, A, D, O, O, P),进行了隐式转换
// 在进行 flatten
scala> books.flatMap(s => s.toUpperCase)
res0: List[Char] = List(H, A, D, O, O, P, H, I, V, E, H, D, F, S)