Scala 文件处理与数据解析实战:成绩统计分析

19 阅读3分钟

一、Scala 文件处理基础

1. 按行读取文本文件

scala
 体验AI代码助手
 代码解读
复制代码
// 基本文件读取
val source = scala.io.Source.fromFile("filename.txt")
val lines = source.getLines()  // 获取行迭代器
source.close()  // 记得关闭资源

2. 数据拆分与类型转换

读取到的文本数据通常需要进行处理:

  • 使用 split() 按分隔符拆分
  • 进行类型转换(字符串转数字)
  • 处理表头行(通常需要跳过)

3. 使用 Case Class 封装数据

case class 是 Scala 中用于封装数据的理想选择,它提供了:

  • 不可变性
  • 自动生成 equalshashCodetoString 方法
  • 模式匹配支持
  • 简洁的创建语法

二、成绩统计系统开发实战

案例:班级成绩综合分析系统

代码

scss
 体验AI代码助手
 代码解读
复制代码
package ex_score

import java.io.FileWriter

object ex03 {
  case class Stu(name: String, yuwen: Double, shuxue: Double, yingyu: Double, zongfen:Double)

  def main(args: Array[String]): Unit = {
    //1. 读出项目根目录下的score.txt文件
    // lines 就是迭代器
    val lines = scala.io.Source.fromFile("score.txt").getLines()

    // 跳过一行,它表示表头
    lines.next() // 即去掉"姓名,语文,数学,英语"

    val stuList = scala.collection.mutable.ListBuffer[Stu]()
    while (lines.hasNext) {
      val line = lines.next()
      val list = line.split(",")
      val total = list(1).toDouble + list(2).toDouble +list(3).toDouble
        stuList += Stu(list(0), list(1).toDouble, list(2).toDouble, list(3).toDouble, total)
    }

    // 3 写入结果到新文件
    val fileWriter = new FileWriter("score_result.txt")

    // 拓展:总分降序排序输出学生列表
    fileWriter.write(s"     xxxxxx 班级成绩分析表  \n\n")
    stuList.sortBy(_.zongfen).reverse.foreach(stu => {
      val avg = stu.zongfen / 3
      fileWriter.write(s"${stu.name}, 语文: ${stu.yuwen}分 数学: ${stu.shuxue}分 英语: ${stu.yingyu}分  总分:${stu.zongfen} 平均分:${avg}\n")
    })
    // 输出英语学科平均分
    fileWriter.write(s"英语平均分:${stuList.map(_.yingyu).sum / stuList.length} 数学平均分:${stuList.map(_.shuxue).sum / stuList.length} 语文平均分:${stuList.map(_.yuwen).sum / stuList.length} \n")

    // 输出单科 英语学科最高分
    fileWriter.write(s"英语最高分:${stuList.map(_.yingyu).max} 数学最高分:${stuList.map(_.shuxue).max} 语文最高分:${stuList.map(_.yuwen).max} \n")
    fileWriter.close()
  }
}

代码结果

3301.png

运行程序后,score_result.txt 内容为:

11.png

代码分析

这个成绩统计系统展示了 Scala 处理结构化数据的完整流程:

  1. 文件读取与预处理

    • 使用 scala.io.Source.fromFile("score.txt").getLines() 创建行迭代器
    • 通过 lines.next() 跳过表头行("姓名,语文,数学,英语")
    • 关键点:注意使用中文逗号 "," 作为分隔符,不是英文逗号
  2. 数据解析与对象创建

    • 使用 while (lines.hasNext) 循环处理每一行数据
    • 每行按中文逗号拆分:line.split(",")
    • 创建 Stu 对象并添加到 ListBuffer
    • 数据结构ListBuffer 提供了可变列表功能,便于动态添加元素
  3. 数据计算与分析

    • 个人成绩统计:为每个学生计算总分和平均分

    • 学科平均分:使用函数式编程计算各科平均分

      scala
       体验AI代码助手
       代码解读
      复制代码
      stuList.map(_.yingyu).sum / stuList.length
      
    • 学科最高分:使用 max 方法获取各科最高分

  4. 结果输出与文件写入

    • 使用 FileWriter 将结果写入新文件
    • 格式化输出,包含清晰的标题和分隔
    • 文件操作完成后调用 close() 方法释放资源
  5. 算法特点

    • 函数式风格:大量使用 mapsummax 等高阶函数
    • 类型安全:明确的类型转换(toDouble
    • 资源管理:注意文件资源的正确关闭

扩展功能示例

代码:基本文件读取示例

scala
 体验AI代码助手
 代码解读
复制代码
package ex_score

object ex01 {
  def main(args: Array[String]): Unit = {
    //1. 读出项目根目录下的score.txt文件
    // lines 就是迭代器
    val lines = scala.io.Source.fromFile("score.txt").getLines()

    // 跳过一行,它表示表头
    lines.next()  // 即去掉"姓名,语文,数学,英语"

    // 按行读取
    for (line <- lines){
      // 一一对应排序
      val list = line.split(",")
      println(s"姓名:${list(0)}")
      println(s"语文:${list(1)}")
      println(s"数学:${list(2)}")
      println(s"英语:${list(3)}")
    }
  }
}

代码结果

11.png

代码:使用 while 循环读取文件

scala
 体验AI代码助手
 代码解读
复制代码
package ex_score

object ex02 {
  def main(args: Array[String]): Unit = {
    //1. 读出项目根目录下的score.txt文件
    // lines 就是迭代器
    val lines = scala.io.Source.fromFile("score.txt").getLines()

    // 跳过一行,它表示表头
    lines.next()  // 即去掉"姓名,语文,数学,英语"

    // 使用 while 循环
    while (lines.hasNext){
      val line = lines.next()
      val list = line.split(",")
      println(s"姓名:${list(0)}")
      println(s"语文:${list(1)}")
      println(s"数学:${list(2)}")
      println(s"英语:${list(3)}")
    }
  }
}

代码结果

22.png

标签:

Scala后端编程语言