object score01 {
case class Stu(name:String, yuwen:Double, shuxue:Double, yingyu:Double)
def main(args: Array[String]): Unit = {
// 0. 创建一个可变list
val stulist = scala.collection.mutable.ListBuffer[Stu]()
// 1. 读入文件 迭代器
val lines = scala.io.Source.fromFile("score.txt").getLines()
lines.next() // 跳过第一行
while(lines.hasNext){
val line = lines.next()
// 字符串拆分
val li = line.split(":")
stulist += Stu(li(0), li(1).toDouble, li(2).toDouble, li(3).toDouble)
}
// 读入数据结束
println("读入数据结束")
stulist.foreach(stu => {
val total = stu.yuwen + stu.yingyu + stu.shuxue
val avg = total / 3
println(s"${stu.name}, 总分: $total, 平均分: $avg")
})
}
}
一、整体结构与核心知识点
代码用到了 Scala 的「样例类(case class)」「可变集合(ListBuffer)」「文件 IO」「循环遍历」等核心特性,流程分为:定义数据结构 → 读取文件 → 解析数据 → 计算成绩 → 输出结果。
二、逐行代码解释
scala
object score01 { // 定义一个单例对象(Scala 程序入口必须是 object)
// 1. 定义样例类:封装学生成绩数据(相当于轻量级的实体类)
case class Stu(name:String, yuwen:Double, shuxue:Double, yingyu:Double)
// 样例类特性:自动生成构造器、toString、equals 等方法,适合封装简单数据
// 参数说明:name=姓名,yuwen=语文成绩,shuxue=数学成绩,yingyu=英语成绩(Double 支持小数)
def main(args: Array[String]): Unit = { // 程序入口方法(main 方法)
// 2. 创建可变ListBuffer:存储多个学生的成绩对象(可变集合,支持动态添加元素)
val stulist = scala.collection.mutable.ListBuffer[Stu]()
// 3. 读取文件:获取文件的行迭代器(按行读取 score.txt)
val lines = scala.io.Source.fromFile("score.txt").getLines()
// Source.fromFile("score.txt"):打开 score.txt 文件(需确保文件在项目根目录)
// getLines():返回文件行的迭代器(一行一行读取,不一次性加载全部内容,省内存)
// 4. 跳过文件第一行(通常是表头,比如“姓名:语文:数学:英语”,不需要解析)
lines.next()
// 5. 循环读取文件每一行(解析数据并封装到 ListBuffer)
while(lines.hasNext){ // hasNext:判断迭代器是否还有下一行数据
val line = lines.next() // 取出当前行的字符串(比如:"小红:98:82:93")
val li = line.split(":") // 按冒号拆分字符串,得到数组(li(0)=姓名,li(1)=语文,依此类推)
// 将拆分后的数据封装为 Stu 对象,添加到 ListBuffer
stulist += Stu(li(0), li(1).toDouble, li(2).toDouble, li(3).toDouble)
// toDouble:将字符串类型的成绩转为 Double 类型(比如 "98" → 98.0)
}
println("读入数据结束") // 提示数据读取完成
// 6. 遍历学生列表,计算并输出总分、平均分
stulist.foreach(stu => { // 遍历 ListBuffer 中的每个 Stu 对象(stu 是单个学生的对象)
val total = stu.yuwen + stu.yingyu + stu.shuxue // 计算总分:语文+英语+数学
val avg = total / 3 // 计算平均分:总分 ÷ 3
// 格式化输出:${} 是 Scala 字符串插值,直接嵌入变量值
println(s"${stu.name}, 总分: $total, 平均分: $avg")
})
}
}
三、关键细节补充
-
文件格式要求
score.txt必须是「冒号分隔」的格式,示例:plaintext
姓名:语文:数学:英语 // 第一行表头(会被 lines.next() 跳过) 小红:98:82:93 小明:90:85:95 小刚:98:83:79 -
核心类 / 方法的作用
case class Stu:替代 Java 的 POJO 类,极简封装数据;ListBuffer:可变列表(Scala 默认 List 不可变,ListBuffer 支持动态添加);Source.fromFile:Scala 内置的文件读取工具;foreach:函数式遍历(替代 for 循环,更简洁);- 字符串插值
s"${}":直接拼接变量,比 Java 的 + 号更优雅。
-
执行结果示例运行代码后控制台会输出:
plaintext
读入数据结束 小红, 总分: 273.0, 平均分: 91.0 小明, 总分: 270.0, 平均分: 90.0 小刚, 总分: 260.0, 平均分: 86.66666666666667
四、潜在注意点
- 如果
score.txt文件不存在,会抛出「文件未找到」异常; - 如果成绩不是数字(比如输入了字母),
toDouble会抛出类型转换异常; - 如果行数据拆分后不足 4 个元素(比如少一个成绩),会抛出数组下标越界异常。