第5章:集合
一、导读
1.1 本章学习目标
第5章讲解 Scala 的集合框架:不可变集合、可变集合、Stream、并行集合。
本章核心学习目标:
- 掌握不可变集合:List、Vector、Map、Set
- 理解可变集合:mutable 包
- 掌握集合操作:map、filter、flatMap、fold
- 了解并行集合
1.2 为什么本章如此重要
Scala 的集合库是其最强大的特性之一。不可变集合和函数式操作是 Scala 代码的核心。
1.3 核心问题引导
不可变集合如何高效地"修改"?
Stream(LazyList)如何实现惰性求值?
并行集合如何加速计算?
二、核心概念详解
5.1 不可变集合
scala
import scala.collection.immutable._
// List: 链表,头部操作 O(1)
val list = List(1, 2, 3)
val newList = 0 :: list // List(0, 1, 2, 3)
// Vector: 随机访问 O(log32 n)
val vec = Vector(1, 2, 3, 4, 5)
val newVec = vec.updated(2, 99) // Vector(1, 2, 99, 4, 5)
// Map
val map = Map("a" -> 1, "b" -> 2)
val newMap = map + ("c" -> 3) // Map(a -> 1, b -> 2, c -> 3)
val updated = map.updated("a", 10) // Map(a -> 10, b -> 2)
// Set
val set = Set(1, 2, 3)
val newSet = set + 4 // Set(1, 2, 3, 4)5.2 集合操作
scala
val nums = List(1, 2, 3, 4, 5)
// 转换
nums.map(_ * 2) // List(2, 4, 6, 8, 10)
nums.filter(_ % 2 == 0) // List(2, 4)
nums.flatMap(n => List(n, n * 10)) // List(1, 10, 2, 20, ...)
// 归约
nums.sum // 15
nums.product // 120
nums.foldLeft(0)(_ + _) // 15
nums.reduce(_ max _) // 5
// 分组
nums.groupBy(_ % 2) // Map(false -> List(2, 4), true -> List(1, 3, 5))
// 拉链
val names = List("Alice", "Bob")
val ages = List(30, 25)
names.zip(ages) // List((Alice,30), (Bob,25))
// 分区
nums.partition(_ > 3) // (List(4, 5), List(1, 2, 3))5.3 LazyList (Stream)
scala
// 惰性列表: 按需计算
lazy val naturals: LazyList[Int] = 1 #:: naturals.map(_ + 1)
println(naturals.take(10).toList) // List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// 斐波那契数列
lazy val fibonacci: LazyList[BigInt] =
BigInt(0) #:: BigInt(1) #:: fibonacci.zip(fibonacci.tail).map(p => p._1 + p._2)
println(fibonacci.take(20).toList)
// 惰性过滤
val primes = LazyList.from(2).filter(isPrime)
def isPrime(n: Int): Boolean = !(2 until n).exists(n % _ == 0)5.4 并行集合
scala
import scala.collection.parallel.CollectionConverters._
// 并行集合
val largeList = (1 to 1000000).toList
// 顺序版本
val sum1 = largeList.map(_ * 2).filter(_ > 500000).sum
// 并行版本
val sum2 = largeList.par.map(_ * 2).filter(_ > 500000).sum
// 注意: 并行集合的操作必须是无副作用的三、实战案例
3.1 案例一:词频统计
scala
val text = """
Scala is a modern programming language.
Scala combines object-oriented and functional programming.
Scala runs on the JVM.
"""
val wordCount = text
.toLowerCase
.split("\\s+")
.filter(_.nonEmpty)
.groupBy(identity)
.view
.mapValues(_.size)
.toMap
// 按频率排序
val sorted = wordCount.toList.sortBy(-_._2)
sorted.foreach { case (word, count) =>
println(f"$word%-15s $count%d")
}四、本章小结
不可变集合是默认选择,安全且高效
LazyList 实现惰性求值
并行集合加速大规模数据处理
五、思考与练习
不可变 List 的 :: 操作的时间复杂度是多少?
并行集合在什么情况下比顺序集合慢?