集合与高阶函数
List/Map、map/filter/fold、For Comprehension。
40 分钟
集合与高阶函数
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 / |