Scala 是否有一种有效的方法来避免使用mapValues进行重复评估?

Scala 是否有一种有效的方法来避免使用mapValues进行重复评估?,scala,Scala,mapValues方法创建一个新的Map,该方法通过应用给定函数将查询结果修改为原始Map。如果两次查询相同的值,则传递给mapValues的函数将被调用两次 例如: case class A(i: Int) { print("A") } case class B(a: A) { print("B") } case class C(b: B) { print("C") } val map = Map("One" -> 1) .mapValues(A) .mapValu

mapValues
方法创建一个新的
Map
,该方法通过应用给定函数将查询结果修改为原始
Map
。如果两次查询相同的值,则传递给
mapValues
的函数将被调用两次

例如:

case class A(i: Int) {
  print("A")
}
case class B(a: A) {
  print("B")
}
case class C(b: B) {
  print("C")
}

val map = Map("One" -> 1)
  .mapValues(A)
  .mapValues(B)
  .mapValues(C)

val a = map.get("One")
val b = map.get("One")
这将打印
ABCABC
,因为每次查询值时都会创建一组新的案例类

我如何才能有效地将其制作成一个具体的
Map
,它预先计算了
mapValues
函数?理想情况下,如果
Map
已经有了具体的值,我想要一个什么都不做的机制

我知道我可以调用
map.map(identity)
,但这会重新计算
map
的索引,这似乎效率低下。如果最后一个
mapValues
转换为
map
,则情况也是如此


视图
方法会将严格的
映射
转换为非严格的
映射
,但似乎没有相反的方法。

您可以在视图上调用
强制
,以强制求值:

scala> val strictMap = map.view.force
ABCstrictMap: scala.collection.immutable.Map[String,C] = Map(One -> C(B(A(1))))

scala> strictMap.get("One")
res1: Option[C] = Some(C(B(A(1))))

scala> strictMap.get("One")
res2: Option[C] = Some(C(B(A(1))))

我会小心地假设这将比一个简单的
映射
执行得更好,尽管如此,如果您需要为2.11或2.12以及将来的Scala版本交叉构建,以修复
mapValues
并完全更改视图系统,那么与噪音和不便相比,差异可能可以忽略不计。

2.13
方法中
mapValues
将被弃用,稍后将被严格重新实现。谢谢,这是一个有趣的选择,但正如您所说,不太可能比
map(identity)
更快。我将饶有兴趣地观看新图书馆的建设进展。