基于 Scala 实现文本文件单词词频统计

0 阅读4分钟

在日常的文本处理场景中,单词词频统计是基础且高频的需求,比如分析文本关键词、统计文档词汇分布等。本文将详细拆解一段 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(表示首次出现)。

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 集合的特性、正则拆分字符串的技巧,以及排序的核心逻辑,在此基础上可拓展处理更复杂的文本。