使用scala实现,统计文件中每个单词的个数
import scala.io.Source
object demo14 {
def main(args: Array[String]): Unit = {
val source = Source.fromFile("Scala/data/words.txt")
val list: List[String] = source.getLines().toList
val wordList: List[String] = list.flatMap(line => {
line.split(",")
})
val wordsMap: Map[String, List[String]] = wordList.groupBy(w => w)
wordsMap.map({
case (word:String,value:List[String]) => {
word + "," + value.length
}
}).foreach(println)
source.close()
}
}
结果为
这里面用到了三个比较重要的函数,map函数,flatMap函数,groupBy函数 简单的说一下每个函数的作用
map函数
map函数,map(func),括号里面接收一个函数,为了方便描述,取名为func,func函数的参数类型与原集合(即map函数要操作的集合)里面元素的类型一致,函数的返回值由自己决定,通常以函数体的最后一行内容作为返回值
而map函数会将 func 函数应用到 原集合 的每一个元素上,映射产生一个新的元素。然后将每一个新元素都放入一个和 原集合 的类型大小都相同的新集合里面
举一个简单的例子
val list:List[Int] =List[Int](1,2,3,4,5)
val list_map: List[Int] = list.map(elem => {
elem + 1
})
原集合的类型是 List[Int],因此map函数返回的结果也是 List[Int] 类型 原集合的元素的数据类型是 Int,因此传入map的 func 函数的参数类型也是Int,这里是匿名函数的简略写法, elem 实际上是 ( elem : Int )
flatMap函数
flatMap( func ),flatMap函数里面同样是接收一个 func函数,与map函数一样,会将这个func函数应用到原集合的每一个元素上
不同的是:flatMap 将某个函数应用到集合中的元素时,对每个元素都会返回一个新集合(而不是一个元素),然后,flatMap把生成的多个集合“拍扁”(或者说“融合”,“连成”)成为一个新的集合并返回。返回的集合与原集合类型相同,但大小可能不同,其中元素的类型也可能不同。
就以上面的代码为例子
val wordList: List[String] = list.flatMap(line => {
line.split(",")
})
原集合是一个 List[String] 类型的list,里面的每个元素都是一行文本内容 这里的 func函数的函数体是 line.split(",") ,由于 line 是原集合的一个元素,是一个字符串,字符串的内容是“java,python,scala”,所以这里可以调用 split() 方法,split() 方法会返回一个 array数组。因此这里 func函数 实际的返回值是 Array[String] 类型的数组
数组也是集合的一种,flatMap会对 func函数 生成的每个集合进行处理,拍扁成一维的list集合 因此flatMap函数的返回结果是 List[String]类型的list列表
关于 Map 和 flatMap 的区别
无论是map函数还是flatMap函数,在其内部,比如map(func),会根据func对每一个元素进行处理,每次处理都会产生一个返回值。在最后,map函数会自动将这些返回值再组合起来放入一个新的集合中,flatMap不过是在放入的时候加上了一个“拍扁”的处理
对于map,如果返回值是一个list,那么这些list最后会组成一个新的list,也就是 List [ list(1,2) , list(3) ]的形式,而flatMap会把每一个list里面的元素取出来,变成 List[ 1,2,3 ]的形式
关于什么时候使用map,什么时候使用flatMap 首先一定要明确,自己最终需要的元素是什么,然后看 map(func),func函数返回值是什么类型
如果返回值是集合,那么需要一个元素就是一个集合可以用map,如果需要的元素在返回值的集合里面,那么就需要flatMap,将元素都取出来
如果返回值不是集合,就是一个个的元素,直接使用map即可
groupBy函数
针对某一个分组字段进行分组,返回结果是一个Map集合 key值是分组字段,数据类型与分组字段的数据类型一致 value值是一个 List 集合,集合里面是分组的全部内容
分组字段通常是原集合的一个元素,或者是这个元素的某一部分 而整个分组,就是原集合全部元素中符合分组字段的元素,这些元素会进入同一个List集合中
同样拿上面的代码举例子
val wordsMap: Map[String, List[String]] = wordList.groupBy(w => w)
w => w 表示的含义是按照元素本身作为分组字段,进行分组 经过flatMap后,此时原集合里面的一个元素,就是一个单词,比如 “java” 此时按照这个单词进行分组,结果是一个Map集合
最后再将每个Map集合传入map中,对每个元素应用模式匹配,计算每个List集合的长度,最后输出Map集合的 key 和 value的长度,即可得出每个单词的个数
|