在日常的文本处理场景中,单词词频统计是基础且高频的需求,比如分析文本关键词、统计文档词汇分布等。本文将详细拆解一段 Scala 代码,该代码实现了从文本文件读取内容、拆分单词、统计词频并按出现次数降序排序的完整流程,帮助理解 Scala 在文本处理中的核心语法和编程思想。
一、代码整体功能概述
这段 Scala 代码的核心目标是:读取指定文本文件(test.txt)的内容,将文本按非单词字符拆分后统计每个单词的出现次数,最后把统计结果按词频从高到低排序并输出。整个流程分为四个核心步骤:文件读取、单词拆分、词频统计、结果排序,覆盖了 Scala IO 操作、集合(数组、可变 Map、List)、循环、排序等核心知识点。
二、代码逐行拆解与解析
1. 程序入口与类定义
object word {
def main(args: Array[String]): Unit = {
// 核心逻辑写在main方法中
}
}
object word:Scala 中使用object定义单例对象,这里作为程序的入口载体,相当于 Java 中的public class Word { ... }。def main(args: Array[String]): Unit:Scala 的程序入口方法,args接收命令行参数,Unit表示方法无返回值(类似 Java 的void)。
2. 读取文本文件内容
val content = scala.io.Source.fromFile("test.txt").mkString;
scala.io.Source.fromFile("test.txt"):Scala 提供的 IO 工具类,用于读取文件内容,test.txt为待读取的文件路径(默认是项目根目录,也可写绝对路径如"D:/data/test.txt")。.mkString:将读取到的文件内容(以字符流形式)转换为完整的字符串,赋值给不可变变量content(Scala 中val定义不可变变量,推荐优先使用)。
3. 拆分字符串为单词数组
val list = content.split("\W+") // 使用空格拆分字符串,结果是一个List
list.foreach(ele => println(ele))
content.split("\W+"):核心拆分逻辑,\W+是正则表达式,代表 “一个或多个非单词字符”(包括空格、逗号、句号、换行符等),相比单纯按空格split(" "),能更精准地拆分英文单词(比如处理hello,world这类带标点的文本)。注意:代码注释中 “结果是一个 List” 是笔误,split方法实际返回Array[String](字符串数组)。list.foreach(ele => println(ele)):遍历拆分后的单词数组,逐行打印每个单词,用于验证拆分结果是否正确。
4. 统计每个单词的出现次数
val map1 = scala.collection.mutable.Map[String,Int]()
list.foreach(word => {
if (map1.contains(word)) {
map1(word) += 1 // 存在:把它的值+1
} else {
map1(word) = 1 // 不存在:把它的值设为1
}
})
-
val map1 = scala.collection.mutable.Map[String,Int]():创建一个可变的 Map 集合,键(Key)为单词(String 类型),值(Value)为出现次数(Int 类型)。Scala 中有可变(mutable)和不可变(immutable)两类集合,这里用可变 Map 是为了方便动态更新词频。 -
list.foreach(word => { ... }):遍历单词数组,对每个单词做判断:- 若单词已在 Map 中(
map1.contains(word)),则将对应值 + 1; - 若单词不在 Map 中,则将该单词作为键,值设为 1(表示首次出现)。
- 若单词已在 Map 中(
5. 统计结果排序输出
val wordList = map1.toList.sortBy(_._2).reverse
wordList.foreach(el => println(el))
map1.toList:Map 集合本身是无序的,无法直接排序,因此先转换为 List 集合sortBy(_._2):按 List 中元组的第二个元素(即词频)升序排序。_._2是 Scala 的匿名函数简写,完整写法为tuple => tuple._2.reverse:将升序排序后的 List 翻转,实现降序排列wordList.foreach(el => println(el)):遍历排序后的 List,打印每个(单词,次数)元组,最终输出词频从高到低的统计结果
三、运行效果示例
假设test.txt文件内容为:
Hello Scala Hello Work Work Work
代码运行后,拆分单词阶段会打印:
Hello
Scala
Hello
Work
Work
Work
最终排序后的输出结果为:
(Work,3)
(Hello,2)
(Scala,1)
总结
这段代码是 Scala 文本处理的案例,围绕 “集合操作 + IO 读取 + 排序” 展开,既体现了 Scala 面向对象的特性,也展现了函数式编程的简洁性。理解该代码的关键在于掌握 Scala 集合的特性、正则拆分字符串的技巧,以及排序的核心逻辑,在此基础上可拓展处理更复杂的文本。