大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
集合与高阶函数
Scala 集合库不可变与可变并存,日常推荐 不可变 List、Map、Set。map / filter / fold 与 For Comprehension 让数据变换更声明式。对照 /roadmaps/scala「Collections」节点。
学习目标
- 熟练使用 List、Map、Set 及常用操作
- 掌握 map、filter、flatMap、foldLeft 等高阶函数
- 读懂并编写 for comprehension
核心概念
不可变 List 与 Map
val nums = List(1, 2, 3, 4, 5)
val doubled = nums.map(_ * 2)
val evens = nums.filter(_ % 2 == 0)
val scores = Map("alice" -> 95, "bob" -> 88)
val alice = scores.get("alice") // Option[Int] = Some(95)
val carol = scores.getOrElse("carol", 0)
val merged = scores ++ Map("carol" -> 92)
println(doubled.sum)
println(merged.mkString(", "))
Option[T] 表示有/无值:Some(v) / None,避免 Java 式 null 歧义。
flatMap 与 fold
case class Page(url: String, tags: List[String])
val pages = List(
Page("a", List("scala", "jvm")),
Page("b", List("fp")),
Page("c", List())
)
val allTags: List[String] =
pages.flatMap(_.tags).distinct.sorted
val wordCount: Map[String, Int] =
allTags.groupBy(identity).view.mapValues(_.size).toMap
val totalChars: Int =
pages.map(_.url.length).foldLeft(0)(_ + _)
println(allTags)
println(totalChars)
flatMap 将「嵌套集合」压平;foldLeft 从左累积,类似 reduce。
For Comprehension
val users = List("alice", "bob", "carol")
val domains = List("example.com", "test.org")
val emails: List[String] =
for
u <- users
d <- domains
if u != "bob"
yield s"$u@$d"
val parsed: List[Int] =
for
s <- List("1", "x", "3")
n <- s.toIntOption
yield n * 10
println(emails.take(3))
println(parsed)
for ... yield desugar 为 map/flatMap/withFilter 组合;toIntOption 失败时过滤掉无效项。
与 Java 对照
| Scala | Java |
|---|---|
List[T](不可变) | List.of / Collections.unmodifiableList |
map / filter | Stream API |
Option[T] | Optional<T> |
| for comprehension | 多层 Stream 链 |
foldLeft | reduce / collect |
Java Stream 与 Scala 集合 API 概念对齐,Scala 语法更短、默认不可变集合更安全。
练习
- 用
groupBy统计字符串列表中各单词出现次数 - 将嵌套
List[List[Int]]用flatMap展平并求和 - 用 for comprehension 生成笛卡尔积并过滤
小结
不可变集合 + 高阶函数 + for 推导是 Scala 日常数据处理三件套。 下一课函数式编程。见 scala-essentials。