单元1 · Scala 环境与基础语法
JVM 环境、sbt、main 函数、val/var、println
- 入口:object 包裹 main 函数;App trait 可简化。
- 变量:val 不可变(推荐)、var 可变;类型推断。
- 插值:s 字符串插值、f 格式化插值。
实训1.1 Hello World 与 main
编写第一个 Scala 程序,输出问候语。
Scala 需要 object 包裹 main;App trait 可简化。
object Hello {
def main(args: Array[String]): Unit = {
println("Hello, Scala!")
println("Scala 融合面向对象与函数式")
}
}
实训1.2 val 与 var
用 val 声明不可变、var 声明可变变量并输出。
val 不可变(推荐);var 可变;类型可推断。
object Demo {
def main(args: Array[String]): Unit = {
val name = "Scala"
var version = 3.3
version = 3.4
println(s"语言:$name")
println(s"版本:$version")
}
}
实训1.3 类型系统与字符串插值
声明各类型变量,用 s 插值器输出。
Scala 静态类型;s 字符串插值、f 格式化。
object Demo {
def main(args: Array[String]): Unit = {
val count: Int = 42
val price: Double = 59.9
val isActive: Boolean = true
val name: String = "Scala"
println(s"计数:$count")
println(f"价格:$price%.2f")
println(s"名称:$name,大写:${name.toUpperCase}")
}
}
实训1.4 输入与转换
用 scala.io.StdIn 读取输入并转换为数字,输出结果。
StdIn.readLine 读取;toIntOption 安全转换返回 Option。
object Demo {
def main(args: Array[String]): Unit = {
print("请输入一个整数:")
val input = scala.io.StdIn.readLine()
input.toIntOption match {
case Some(n) => println(s"$n 的平方是 ${n * n}")
case None => println("输入无效")
}
}
}
单元2 · 数据类型与运算符
数值类型、算术/比较/逻辑、类型转换、Option
- 类型:Int/Double/Boolean/String;Int 相除整除。
- 转换:toInt/toDouble;toIntOption 安全转换。
- Option:Some/None;getOrElse 兜底。
实训2.1 基础运算
给定整数 17 和 5,输出和、差、积、整除商、余数、幂。
Int 相除整除;% 取余;math.pow 幂运算。
object Demo {
def main(args: Array[String]): Unit = {
val a = 17
val b = 5
println(s"和:${a + b}")
println(s"差:${a - b}")
println(s"积:${a * b}")
println(s"整除商:${a / b}")
println(s"余数:${a % b}")
println(s"2 的 10 次方:${math.pow(2, 10).toInt}")
}
}
实训2.2 浮点运算
计算半径为 7.5 的圆的周长与面积。
math.Pi 圆周率;f 插值器控制小数位。
object Demo {
def main(args: Array[String]): Unit = {
val r = 7.5
val circumference = 2 * math.Pi * r
val area = math.Pi * r * r
println(f"周长:$circumference%.4f")
println(f"面积:$area%.4f")
}
}
实训2.3 比较与逻辑运算
a=8、b=12,输出 a>b、a!=b、a<10 && b>10、!(a==8)。
== 结构相等;&& 与、|| 或、! 非。
object Demo {
def main(args: Array[String]): Unit = {
val a = 8
val b = 12
println(s"a > b:${a > b}")
println(s"a != b:${a != b}")
println(s"a<10 && b>10:${a < 10 && b > 10}")
println(s"!(a == 8):${!(a == 8)}")
}
}
实训2.4 类型转换与 Option
演示 toInt/toDouble 与 toIntOption 安全转换。
toIntOption 失败返回 None;getOrElse 提供默认值。
object Demo {
def main(args: Array[String]): Unit = {
val s = "42"
val n = s.toInt + 8
println(s"转换加 8:$n")
val bad: Option[Int] = "abc".toIntOption
println(s"非法转换:$bad")
println(s"兜底值:${bad.getOrElse(-1)}")
val d = 3.7
println(s"3.7 转 Int:${d.toInt}")
println(s"Int 转 Double:${n.toDouble}")
}
}
单元3 · 流程控制:分支结构
if/else、match 表达式、模式匹配基础
- if:是表达式,可返回值。
- match:表达式;case 分支;_ 兜底;守卫。
- 类型匹配:case x: Type 按类型分发。
实训3.1 if 判断成绩等级
成绩 score=85,输出等级:>=90 优秀、>=80 良好、>=60 及格、否则不及格。
Scala if 是表达式,可返回值。
object Demo {
def main(args: Array[String]): Unit = {
val score = 85
if (score >= 90) {
println("优秀")
} else if (score >= 80) {
println("良好")
} else if (score >= 60) {
println("及格")
} else {
println("不及格")
}
}
}
实训3.2 match 判断星期
用 match 把数字 1-7 映射为星期。
match 是表达式;case 分支;_ 通配兜底。
object Demo {
def main(args: Array[String]): Unit = {
val day = 4
val name = day match {
case 1 => "星期一"
case 2 => "星期二"
case 3 => "星期三"
case 4 => "星期四"
case 5 => "星期五"
case 6 => "星期六"
case 7 => "星期日"
case _ => "无效输入"
}
println(s"$day -> $name")
}
}
实训3.3 if 表达式返回值
用 if 作为表达式赋值,判断奇数偶数。
if 最后一个表达式即为返回值,无需 return。
object Demo {
def main(args: Array[String]): Unit = {
val n = 15
val parity = if (n % 2 == 0) "偶数" else "奇数"
println(s"$n 是$parity")
val score = 85
val grade = if (score >= 90) "优秀"
else if (score >= 60) "及格"
else "不及格"
println(s"$score 分:$grade")
}
}
实训3.4 match 守卫与类型匹配
用 match 加守卫条件、类型匹配处理不同情况。
case 可带 if 守卫;case x: Type 类型匹配。
object Demo {
def main(args: Array[String]): Unit = {
def describe(x: Any): String = x match {
case i: Int if i > 100 => s"大整数 $i"
case i: Int => s"整数 $i"
case s: String => s"字符串「$s」长度 ${s.length}"
case _ => "其他类型"
}
println(describe(200))
println(describe(42))
println(describe("hello"))
println(describe(3.14))
}
}
单元4 · 循环结构
for 推导式、while、break/continue 模拟
- for:遍历 range;to 含端点。
- yield:for 推导式生成新集合。
- while:条件循环;无 break 用守卫模拟。
实训4.1 for 求和 1 到 100
用 for 推导式计算 1+2+...+100 的和并输出。
for (i <- 1 to 100) 遍历闭区间;to 含端点。
object Demo {
def main(args: Array[String]): Unit = {
var sum = 0
for (i <- 1 to 100) {
sum += i
}
println(s"1 到 100 的和:$sum")
val sum2 = (1 to 100).sum
println(s"range.sum:$sum2")
}
}
实训4.2 打印乘法表
输出 9x9 乘法表,每行一个乘数。
嵌套 for;1 to i 控制内层次数。
object Demo {
def main(args: Array[String]): Unit = {
for (i <- 1 to 9) {
var row = ""
for (j <- 1 to i) {
row += s"${j}x$i=${i * j} "
}
println(row)
}
}
}
实训4.3 for 推导式与 yield
用 yield 从 for 推导式生成新集合。
for + yield 生成新集合;guard if 过滤。
object Demo {
def main(args: Array[String]): Unit = {
val doubled = for (i <- 1 to 10) yield i * 2
println(s"翻倍:$doubled")
val evenSquares = for {
i <- 1 to 10
if i % 2 == 0
} yield i * i
println(s"偶数平方:$evenSquares")
}
}
实训4.4 while 与守卫
用 while 输出 1 到 20 中能被 3 整除的数(含守卫)。
while 条件循环;Scala 无 break/continue,用守卫或 return。
object Demo {
def main(args: Array[String]): Unit = {
var i = 1
while (i <= 20) {
if (i == 15) i = 21 // 模拟 break
else if (i % 3 == 0) println(i)
i += 1
}
val nums = (1 to 20).filter(_ % 3 == 0).takeWhile(_ < 15)
println(s"函数式写法:$nums")
}
}
单元5 · 函数
函数定义、默认参数、命名参数、高阶函数、Lambda
- 函数:def 参数: 类型 = 表达式。
- 参数:默认参数、命名参数。
- 高阶:函数参数 (T) => R;Lambda。
实训5.1 定义求和函数
定义 add 函数返回两数之和并调用输出。
def 函数名(参数: 类型): 返回类型 = 表达式。
object Demo {
def add(a: Int, b: Int): Int = {
a + b
}
def main(args: Array[String]): Unit = {
println(s"add(10, 20) = ${add(10, 20)}")
println(s"add(3, 7) = ${add(3, 7)}")
}
}
实训5.2 默认参数与命名参数
定义带默认参数的函数,用命名参数调用。
默认参数 = 值;调用可命名参数任意顺序。
object Demo {
def greet(name: String, greeting: String = "你好"): String = {
s"$greeting,$name!"
}
def main(args: Array[String]): Unit = {
println(greet("小明"))
println(greet("小红", "早上好"))
println(greet(greeting = "欢迎", name = "小刚"))
}
}
实训5.3 高阶函数与 Lambda
定义接收函数参数的高阶函数,演示 Lambda 语法。
参数类型 (Int) => Int;Lambda (x: Int) => 表达式。
object Demo {
def applyTwice(x: Int, op: Int => Int): Int = {
op(op(x))
}
def main(args: Array[String]): Unit = {
val double: Int => Int = x => x * 2
println(s"翻倍两次:${applyTwice(3, double)}")
val nums = List(1, 2, 3, 4, 5, 6)
val evenSquares = nums.filter(x => x % 2 == 0).map(x => x * x)
println(s"偶数平方:$evenSquares")
}
}
实训5.4 函数字面量与占位符
用 _ 占位符简化 Lambda,演示函数作为一等公民。
_ 占位符简化;val f = (_: Int) + 1 函数值。
object Demo {
def main(args: Array[String]): Unit = {
val addOne: Int => Int = _ + 1
val multiply: (Int, Int) => Int = _ * _
println(s"addOne(5) = ${addOne(5)}")
println(s"multiply(3, 4) = ${multiply(3, 4)}")
val nums = List(1, 2, 3, 4)
println(s"map _ * 2:${nums.map(_ * 2)}")
println(s"filter _ % 2 == 0:${nums.filter(_ % 2 == 0)}")
}
}
单元6 · 集合
List、Set、Map、集合操作、不可变集合
- List:不可变;:+ 添加;sorted/max。
- 函数式:map/filter/reduce/foldLeft。
- Set/Map:去重、集合运算、键值对。
实训6.1 List 操作
创建 List,添加元素、遍历、排序、求最值。
List 不可变;:: 前插;:+ 后接;sorted/max。
object Demo {
def main(args: Array[String]): Unit = {
val nums = List(12, 45, 7, 89, 33)
val nums2 = nums :+ 60
println(s"原列表:$nums")
println(s"添加后:$nums2")
println(s"大小:${nums2.size}")
println(s"最大值:${nums2.max}")
println(s"排序:${nums2.sorted}")
println(s"反转:${nums2.reverse}")
}
}
实训6.2 集合函数式操作
用 map、filter、reduce、foldLeft 处理数据。
map/filter 转换;reduce 归约;foldLeft 带初始值。
object Demo {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4, 5, 6)
println(s"翻倍:${nums.map(_ * 2)}")
println(s"偶数:${nums.filter(_ % 2 == 0)}")
println(s"总和:${nums.sum}")
println(s"乘积:${nums.reduce(_ * _)}")
println(s"foldLeft 带初始:${nums.foldLeft(100)(_ + _)}")
}
}
实训6.3 Set 与 Map
用 Set 去重、Map 存键值,演示集合运算。
Set 去重;intersect/union;Map 键值对。
object Demo {
def main(args: Array[String]): Unit = {
val nums = List(3, 1, 4, 1, 5, 9, 2, 6)
val unique = nums.toSet
println(s"去重:$unique")
val a = Set(1, 2, 3, 4)
val b = Set(3, 4, 5, 6)
println(s"交集:${a.intersect(b)}")
println(s"并集:${a.union(b)}")
println(s"差集:${a.diff(b)}")
val ages = Map("张三" -> 20, "李四" -> 22)
ages.foreach { case (name, age) => println(s"$name:$age 岁") }
println(s"张三年龄:${ages.getOrElse("张三", 0)}")
}
}
实训6.4 集合分组与归约
用 groupBy、take、maxBy 等函数处理数据。
groupBy 分组;sorted.take 取前 n;maxBy 找最大。
object Demo {
def main(args: Array[String]): Unit = {
val scores = List(55, 90, 72, 88, 45, 98)
val groups = scores.groupBy(s => if (s >= 60) "及格" else "不及格")
groups.foreach { case (k, v) => println(s"$k:${v.size} 人") }
val top3 = scores.sorted(Ordering.Int.reverse).take(3)
println(s"前三:$top3")
val total = scores.sum
println(f"总分:$total,平均:${total.toDouble / scores.size}%.1f")
}
}
单元7 · 类与对象
类定义、构造函数、继承、case class、单例对象
- 类:class + 构造参数属性。
- 继承:extends + override + super。
- case class:自动生成 equals/copy/解构。
实训7.1 定义类与对象
定义 Student 类(属性、方法),实例化并调用。
class 定义类;var 属性可读写;new 实例化。
class Student(val name: String, var score: Double) {
def info: String = s"$name,成绩 $score 分"
}
object Demo {
def main(args: Array[String]): Unit = {
val stu = new Student("小明", 92.5)
println(stu.info)
stu.score = 95.0
println(s"修改后:${stu.info}")
}
}
实训7.2 继承与重写
定义 Animal 基类和 Dog 子类,重写方法。
extends 继承;override 重写;super 调用父类。
class Animal(val name: String) {
def speak: String = "动物叫声"
}
class Dog(name: String) extends Animal(name) {
override def speak: String = s"${super.speak}:汪汪!"
}
object Demo {
def main(args: Array[String]): Unit = {
val dog = new Dog("旺财")
println(dog.speak)
println(s"是 Animal 子类:${dog.isInstanceOf[Animal]}")
}
}
实训7.3 case class 样例类
用 case class 定义不可变数据类,体验自动生成的方法。
case class 自动生成 equals/toString/copy/模式匹配支持。
case class User(id: Int, name: String, email: String)
object Demo {
def main(args: Array[String]): Unit = {
val u1 = User(1, "Alice", "alice@example.com")
val u2 = u1.copy(name = "Alicia")
println(s"u1:$u1")
println(s"相等:${u1 == u2}")
println(s"copy 后:$u2")
u1 match {
case User(id, name, _) => println(s"解构:id=$id, name=$name")
}
}
}
实训7.4 单例对象与伴生对象
用 object 定义单例,用伴生对象实现静态成员。
object 单例;class + object 同名构成伴生关系,可互相访问私有成员。
class Circle(val radius: Double) {
def area: Double = Circle.pi * radius * radius
}
object Circle {
private val pi = math.Pi
def apply(radius: Double): Circle = new Circle(radius)
val UNIT: Circle = new Circle(1.0)
}
object Demo {
def main(args: Array[String]): Unit = {
val c = Circle(3.0) // apply 工厂
println(f"面积:${c.area}%.4f")
println(f"单位圆面积:${Circle.UNIT.area}%.4f")
}
}
单元8 · 函数式编程核心
不可变性、模式匹配、Option、Either、集合函数
- Option:避免 null;map/getOrElse/match。
- 模式匹配:解构元组、列表、Option。
- Either:Left 错误、Right 成功。
实训8.1 Option 处理
用 Option 表示可选值,map/getOrElse/match 处理。
Option 避免 null;Some/None;getOrElse 兜底。
object Demo {
def safeDiv(a: Int, b: Int): Option[Int] =
if (b == 0) None else Some(a / b)
def main(args: Array[String]): Unit = {
println(s"10/2:${safeDiv(10, 2).getOrElse(-1)}")
println(s"10/0:${safeDiv(10, 0).getOrElse(-1)}")
safeDiv(10, 0) match {
case Some(v) => println(s"结果:$v")
case None => println("除数为 0,返回默认值")
}
val doubled = safeDiv(10, 2).map(_ * 2)
println(s"map 翻倍:$doubled")
}
}
实训8.2 模式匹配高级
用模式匹配解构元组、列表、Option。
模式匹配支持解构;:: 匹配列表头尾。
object Demo {
def main(args: Array[String]): Unit = {
val point = (3, -2)
point match {
case (0, 0) => println("原点")
case (x, 0) => println(s"x 轴上,x=$x")
case (0, y) => println(s"y 轴上,y=$y")
case (x, y) if x > 0 && y > 0 => println("第一象限")
case (x, y) => println(s"其它位置:($x, $y)")
}
val list = List(1, 2, 3, 4, 5)
list match {
case head :: tail => println(s"头部:$head,尾部:$tail")
case Nil => println("空列表")
}
}
}
实训8.3 Either 错误处理
用 Either 区分错误与成功路径。
Either[L, R]:Left 错误、Right 成功;模式匹配处理。
object Demo {
def parseScore(s: String): Either[String, Int] =
s.toIntOption match {
case Some(n) if n >= 0 && n <= 100 => Right(n)
case Some(_) => Left(s"分数越界:$s")
case None => Left(s"无法解析:$s")
}
def main(args: Array[String]): Unit = {
List("85", "120", "abc").foreach { s =>
parseScore(s) match {
case Right(score) => println(s"$s -> 有效分数 $score")
case Left(err) => println(s"$s -> 错误:$err")
}
}
}
}
实训8.4 集合流水线
用 map/filter/flatMap/groupBy 构建数据处理流水线。
不可变集合链式操作;flatMap 展平;collect 过滤映射。
object Demo {
def main(args: Array[String]): Unit = {
val sentences = List(
"scala is powerful",
"scala is concise",
"java is verbose"
)
val words = sentences.flatMap(_.split(" "))
println(s"单词列表:$words")
val longWords = words.filter(_.length > 4)
println(s"长度>4:$longWords")
val counts = words.groupBy(identity).view.mapValues(_.size).toMap
println(s"词频:$counts")
}
}
单元9 · 不可变与集合深入
List 不可变、fold、zip、Range、Stream/LazyList
- fold:foldLeft/foldRight 归约。
- zip:按位置配对;unzip 拆分。
- 惰性:LazyList 无限序列。
实训9.1 fold 与归约
用 foldLeft/foldRight/reduce 实现归约。
foldLeft 从左到右带初始值;reduce 无初始值。
object Demo {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4, 5)
println(s"foldLeft 求和:${nums.foldLeft(0)(_ + _)}")
println(s"foldLeft 拼接:${nums.foldLeft("")((acc, n) => acc + n)}")
println(s"reduce 求积:${nums.reduce(_ * _)}")
println(s"foldRight:${nums.foldRight(0)(_ + _)}")
}
}
实训9.2 zip 与元组操作
用 zip 合并两个集合,用 unzip 拆分。
zip 按位置配对;unzip 拆回两个集合。
object Demo {
def main(args: Array[String]): Unit = {
val names = List("张三", "李四", "王五")
val scores = List(90, 85, 78)
val pairs = names.zip(scores)
pairs.foreach { case (n, s) => println(s"$n:$s 分") }
val (names2, scores2) = pairs.unzip
println(s"姓名:$names2")
println(s"分数:$scores2")
}
}
实训9.3 Range 与生成
用 Range 生成序列,演示 until/to/by 步长。
1 to 10 含端点;until 不含;by 步长。
object Demo {
def main(args: Array[String]): Unit = {
val r1 = 1 to 10
println(s"1 to 10:$r1")
val evens = 2 to 10 by 2
println(s"偶数:$evens")
val backwards = 5 to 1 by -1
println(s"倒序:$backwards")
val squares = (1 to 5).map(i => i * i)
println(s"平方:$squares")
}
}
实训9.4 LazyList 惰性序列
用 LazyList 生成无限斐波那契序列并取前 n 项。
LazyList 惰性求值;#:: 构建无限流;take 取前 n。
object Demo {
def main(args: Array[String]): Unit = {
def fibs(a: Int, b: Int): LazyList[Int] = a #:: fibs(b, a + b)
val fib = fibs(0, 1).take(10).toList
println(s"斐波那契前 10:$fib")
}
}
单元10 · 并发与 Actor 模型
Future、线程池、并发执行、同步等待
- Future:异步计算;Await 等待。
- 组合:map/flatMap/for 推导式。
- 并行:.par 并行集合;recover 失败恢复。
实训10.1 Future 基础
用 Future 异步执行任务,Await 等待结果。
Future 异步计算;ExecutionContext 线程池;Await.result 等待。
import scala.concurrent.{Future, Await}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
object Demo {
def main(args: Array[String]): Unit = {
val future = Future {
Thread.sleep(100)
42
}
val result = Await.result(future, 2.seconds)
println(s"Future 结果:$result")
}
}
实训10.2 Future 组合
用 map、flatMap、for 推导式组合多个 Future。
map 转换;flatMap 串联;for 推导式并发组合。
import scala.concurrent.{Future, Await}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
object Demo {
def main(args: Array[String]): Unit = {
val f1 = Future { Thread.sleep(100); 10 }
val f2 = Future { Thread.sleep(100); 20 }
val sum = for {
a <- f1
b <- f2
} yield a + b
println(s"组合结果:${Await.result(sum, 2.seconds)}")
}
}
实训10.3 并行集合
用 .par 并行处理集合,演示并行 map。
.par 将集合转为并行集合;多核并行计算。
object Demo {
def main(args: Array[String]): Unit = {
val nums = (1 to 1000).toList
val seqResult = nums.map(_ * 2)
val parResult = nums.par.map(_ * 2).seq
println(s"并行结果一致:${seqResult == parResult}")
println(s"并行前 5 个:${parResult.take(5)}")
}
}
实训10.4 失败恢复
用 recover 与 recoverWith 处理 Future 失败。
recover 将失败转换为成功值;recoverWith 返回新 Future。
import scala.concurrent.{Future, Await}
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
object Demo {
def main(args: Array[String]): Unit = {
val risky = Future {
if (math.random() > 0.3) 100 else throw new RuntimeException("模拟失败")
}
val safe = risky.recover {
case e: RuntimeException => -1
}
println(s"恢复后结果:${Await.result(safe, 2.seconds)}")
}
}
单元11 · 面向对象与函数式结合
trait、隐式转换、柯里化、偏函数
- trait:行为组合;with 混入。
- 柯里化:多参数列表;部分应用。
- 隐式:implicit 参数与转换。
实训11.1 trait 混入
定义 trait 并混入到类中,实现行为组合。
trait 类似接口但可带实现;with 混入多个 trait。
trait Logger {
def log(msg: String): Unit = println(s"[LOG] $msg")
}
trait Timestamp {
def now: String = java.time.LocalTime.now.toString
}
class Service extends Logger with Timestamp {
def run(): Unit = log(s"服务启动于 $now")
}
object Demo {
def main(args: Array[String]): Unit = {
val svc = new Service
svc.run()
}
}
实训11.2 柯里化
用柯里化拆分参数列表,实现部分应用。
多个参数列表 (a)(b);部分应用传入部分参数。
object Demo {
def add(a: Int)(b: Int): Int = a + b
def main(args: Array[String]): Unit = {
println(s"柯里化 add(1)(2) = ${add(1)(2)}")
val add5 = add(5) _
println(s"部分应用 add5(3) = ${add5(3)}")
}
}
实训11.3 偏函数
用 PartialFunction 定义只处理部分输入的函数。
PartialFunction 带 isDefinedAt;orElse 组合。
object Demo {
def main(args: Array[String]): Unit = {
val positive: PartialFunction[Int, String] = {
case n if n > 0 => s"正数 $n"
}
val negative: PartialFunction[Int, String] = {
case n if n < 0 => s"负数 $n"
}
val zero: PartialFunction[Int, String] = {
case 0 => "零"
}
val handler = positive.orElse(negative).orElse(zero)
List(5, -3, 0).foreach(n => println(handler(n)))
}
}
实训11.4 隐式参数与隐式转换
用 implicit 参数提供默认上下文,演示隐式转换。
implicit 参数自动填充;隐式转换扩展类型能力。
case class Price(amount: Double)
object Demo {
implicit val taxRate: Double = 0.13
def withTax(price: Price)(implicit rate: Double): Double =
price.amount * (1 + rate)
def main(args: Array[String]): Unit = {
val p = Price(100.0)
println(f"含税价:${withTax(p)}%.2f")
}
}
单元12 · 综合项目实训
综合运用 Scala 知识完成项目
- 综合:case class、集合、模式匹配、Try。
- 工程化:sortBy、groupBy、f 格式化。
实训12.1 学生成绩统计
用 case class 与集合处理学生成绩,输出平均与排名。
case class + List + sortBy + 统计函数组合。
case class Student(name: String, chinese: Double, math: Double) {
def average: Double = (chinese + math) / 2
}
object Demo {
def main(args: Array[String]): Unit = {
val students = List(
Student("张三", 90, 85),
Student("李四", 78, 92),
Student("王五", 88, 76)
)
val sorted = students.sortBy(-_.average)
println("姓名 语文 数学 平均")
sorted.foreach { s =>
println(f"${s.name} ${s.chinese} ${s.math} ${s.average}%.1f")
}
val avg = students.map(_.average).sum / students.size
println(f"全班平均:$avg%.1f")
println(s"第一名:${sorted.head.name}")
}
}
实训12.2 词频统计器
统计文本单词出现次数,输出出现最多的单词。
flatMap 拆词 + groupBy + maxBy 统计。
object Demo {
def main(args: Array[String]): Unit = {
val text = "scala is powerful scala is concise scala is fun"
val words = text.split(" ").toList
val freq = words.groupBy(identity).view.mapValues(_.size).toMap
freq.toList.sortBy(-_._2).foreach { case (w, c) => println(s"$w:$c") }
val top = freq.maxBy(_._2)
println(s"出现最多:${top._1},${top._2} 次")
}
}
实训12.3 购物车结算
用 case class 实现购物车:添加商品、计算总价、按小计排序。
case class + List + map 计算 + sorted 排序 + sum 合计。
case class CartItem(name: String, price: Double, qty: Int) {
def subtotal: Double = price * qty
}
object Demo {
def main(args: Array[String]): Unit = {
val items = List(
CartItem("Scala 教程", 59.0, 2),
CartItem("编程鼠标", 129.0, 1),
CartItem("机械键盘", 399.0, 1)
)
items.sortBy(-_.subtotal).foreach { it =>
println(f"${it.name} x${it.qty} = ${it.subtotal}%.2f 元")
}
val total = items.map(_.subtotal).sum
println(f"总计:$total%.2f 元")
}
}
实训12.4 简单计算器
实现支持 + - * / 的计算器:解析表达式并计算。
split 解析 + match 分发 + Try 错误处理。
import scala.util.Try
object Demo {
def calculate(expr: String): Try[Double] = Try {
val parts = expr.split(" ")
require(parts.length == 3, "格式错误,示例:3 + 5")
val a = parts(0).toDouble
val b = parts(2).toDouble
parts(1) match {
case "+" => a + b
case "-" => a - b
case "*" => a * b
case "/" =>
require(b != 0, "除数不能为 0")
a / b
case op => throw new IllegalArgumentException(s"不支持的运算符:$op")
}
}
def main(args: Array[String]): Unit = {
List("10 + 5", "10 * 3", "10 / 0", "abc + 1").foreach { expr =>
calculate(expr) match {
case scala.util.Success(v) => println(s"$expr = $v")
case scala.util.Failure(e) => println(s"$expr -> 错误:${e.getMessage}")
}
}
}
}