实训一:可变 Map 实现图书馆管理系统
代码结构解析
import scala.collection.mutable
object LibraryMapSystem {
def main(args: Array[String]): Unit = {
// 代码实现...
}
}
解析:
import scala.collection.mutable- 导入可变集合包object LibraryMapSystem- 创建单例对象main方法 - 程序入口点
1. 创建可变 Map
val library = mutable.Map[String, (String, String, Int)](
"B001" -> ("Scala 编程", "Martin Odersky", 5),
"B002" -> ("Java 核心技术", "Cay Horstmann", 3),
"B003" -> ("Python 学习手册", "Mark Lutz", 7)
)
解析:
mutable.Map[String, (String, String, Int)]- 创建键为String,值为三元组的可变Map- 键:书籍编号(如 "B001")
- 值:元组包含(书籍名称,作者,库存数量)
- 使用
->操作符创建键值对
2. 添加新书籍
library += ("B004" -> ("数据结构与算法", "严蔚敏", 4))
library += ("B005" -> ("设计模式", "Erich Gamma", 6))
解析:
+=操作符 - 向可变Map添加新元素- 语法:
map += (key -> value) - 如果键已存在,会更新对应的值
3. 查询书籍信息
val bookId = "B002"
val bookInfo = library.get(bookId)
bookInfo match {
case Some((name, author, stock)) =>
println(s"找到书籍: $name, 作者: $author, 库存: $stock")
case None =>
println(s"未找到编号为 $bookId 的书籍")
}
解析:
library.get(bookId)- 安全获取值,返回Option类型Option类型:Some(value)或None- 使用模式匹配处理两种可能情况
- 避免直接使用
library(bookId)可能抛出异常
4. 修改库存数量
library.get(updateId) match {
case Some((name, author, stock)) =>
library(updateId) = (name, author, stock + 2)
println(s"修改后: ${library(updateId)}")
case None =>
println(s"未找到要修改的书籍")
}
解析:
- 先检查书籍是否存在
- 使用
library(key) = newValue语法更新值 - 元组是不可变的,所以创建新的元组替换原值
- 体现了可变Map的特性:可以修改已存在的键值对
5. 删除书籍
library -= removeId
解析:
-=操作符 - 从Map中移除指定键的元素- 语法:
map -= key - 如果键不存在,操作不会产生错误
6. 遍历打印
library.foreach { case (id, (name, author, stock)) =>
println(s"编号: $id, 书名: $name, 作者: $author, 库存: $stock")
}
解析:
foreach- 遍历集合的每个元素- 使用模式匹配解构键值对
case (id, (name, author, stock))- 分别提取键和元组的各个部分
实训二:可变 Set 实现图书馆管理系统
1. 创建可变 Set
val library1 = mutable.Set[String](
"Scala 程序设计",
"Java 编程思想",
"Scala 实战"
)
解析:
mutable.Set[String]- 创建字符串类型的可变Set- Set特性:元素唯一,无序
- 初始化时传入初始元素
2. 添加和删除元素
library1 += "Python 从入门到实践"
library1 += "数据结构与算法分析"
library1 -= "Scala 实战"
解析:
+=- 向Set添加元素,如果元素已存在则无变化-=- 从Set移除元素,如果元素不存在则无变化- 这些操作都会修改原Set
3. 检查元素存在性
val searchBook = "Python 从入门到实践"
if (library1.contains(searchBook)) {
println(s"《$searchBook》在图书馆中")
} else {
println(s"《$searchBook》不在图书馆中")
}
解析:
contains方法 - 检查Set是否包含指定元素- 返回布尔值:
true或false - 时间复杂度接近 O(1),查找效率高
4. 集合运算
// 创建第二个Set
val library2 = mutable.Set[String](
"Java 编程思想",
"Python 从入门到实践",
"C++ Primer",
"算法导论"
)
// 并集
val unionSet = library1.union(library2)
// 交集
val intersectSet = library1.intersect(library2)
// 差集
val diffSet = library1.diff(library2)
解析:
并集 (union):
- 包含两个集合中的所有元素
- 重复元素只出现一次
- 数学表示:A ∪ B
交集 (intersect):
- 只包含两个集合中都存在的元素
- 数学表示:A ∩ B
差集 (diff):
- 包含在第一个集合但不在第二个集合中的元素
library1.diff(library2)= 在library1中但不在library2中的书籍- 数学表示:A - B
重要特性对比
| 特性 | 可变Map | 可变Set |
|---|---|---|
| 元素类型 | 键值对 | 单个元素 |
| 查询方式 | 通过键查询 | 直接检查元素存在性 |
| 添加操作 | map += (key -> value) | set += element |
| 删除操作 | map -= key | set -= element |
| 主要用途 | 存储关联数据 | 存储唯一元素集合 |
学习要点总结
-
可变集合 vs 不可变集合
- 可变集合:可以直接修改
- 不可变集合:操作返回新集合
-
Option类型的安全使用
- 使用
get方法避免空指针异常 - 模式匹配处理
Some和None
- 使用
-
集合操作符
+=和-=用于修改可变集合- 集合运算:
union,intersect,diff