【发布时间】:2012-03-13 11:51:01
【问题描述】:
我需要处理代表人们的大量记录(数百万)。我想根据出生年份创建一个分区,然后分别处理每个组。我正在尝试创建一个功能解决方案(无/最少的可变数据),以便它是线程安全的并且可以并行化。
在我的第一次尝试中,我创建了一个尾递归函数,它构建了一个 Map[Int, IndexedSeq],将每个出生年份映射到一系列人员记录。我需要一个索引序列,因为我将对每个组中的人进行随机访问。这是我的代码:
@tailrec
def loop(people: Seq[Person],
map: Map[Int, IndexedSeq[Person]] = Map()): Map[Int, IndexedSeq[Person]] = {
if (people.isEmpty) map
else {
val person = people.head
val yearOfBirth = person.yearOfBirth
val seq = map.getOrElse(yearOfBirth, IndexedSeq())
loop(people.tail, map + (yearOfBirth -> (seq :+ person)))
}
}
这可行,但效率不高。通过允许少量非常局部的可变性,我可以做得更好。如果所有可变变量都在堆栈上,那么代码仍然是线程安全的,只要输出 Map 是不可变的。
我想通过在内部构建一个可变的Map[Int, List[Person]] 来实现这一点,然后将其有效地转换为一个不可变的Map[Int, IndexedSeq[Person]] 作为返回值。
如何以最有效的方式将可变的Map 的List 项目转换为不可变的Map[Int, IndexedSeq[Person]]?请注意,每个出生年份组中的人没有特定的顺序。
【问题讨论】:
-
一个小问题,可能无关紧要:因为你在出生年份进行分区,AFAICT 你永远不会在这个线程之外传递地图本身。
标签: scala map immutability