Scala:如果从 GroupBy 创建 Map,为什么无法更改 Map 中的可变值

Scala: Why the mutable value inside Map cannot be changed if the Map is created from GroupBy

提问人:林鼎棋 提问时间:3/16/2019 更新时间:3/16/2019 访问量:102

问:

我想创建一个 Map 对象,其键为整数,值为可变 Set。但是,当我从函数创建 Map 对象时,可变 Set 中的值无法再更改。谁能告诉我为什么会这样?GroupBy

import scala.collection.mutable

val groupedMap: Map[Int, mutable.Set[Int]] = 
    List((1,1),(1,2),(2,3))
        .groupBy(_._1)
        .mapValues(_.map(_._2).to[mutable.Set])

val originalMap: Map[Int, mutable.Set[Int]] =
    Map(1 -> mutable.Set(1, 2), 2 -> mutable.Set(3))

println(groupedMap) // Map(1 -> Set(1, 2), 2 -> Set(3))
println(originalMap) // Map(1 -> Set(1, 2), 2 -> Set(3))

groupedMap(1) += 99
originalMap(1) += 99

println(groupedMap) // Map(1 -> Set(1, 2), 2 -> Set(3))  <- HERE IS THE PROBLEM, THE VALUE 99 CAN NOT BE ADDED TO MY MUTABLE SET!
println(originalMap) // Map(1 -> Set(99, 1, 2), 2 -> Set(3))
斯卡拉 字典 分组依据 设置 可变

评论


答:

11赞 Dima 3/16/2019 #1

.mapValues是懒惰的,这意味着你给它的函数在你每次访问值时都会执行,所以,当你这样做时,它会运行你的转换,返回一个你加 99 的函数,然后丢弃它groupedMap(1) += 99Set

然后,当您打印它时,它会再次运行转换......并打印原始内容。

如果上述内容似乎不清楚,请尝试运行以下代码片段作为说明:

 val foo = Map("foo" -> "bar")
   .mapValues { _ => println("mapValues"); "baz" }

 println(foo("foo") + foo("foo"))

这是使用可变数据时遇到的众多问题之一。别这样。在 scala 的 99% 用例中,它不需要。所以,最好假装它根本不存在,直到你对语言有足够的掌握,能够明确地确定剩下的 1%。

评论

0赞 林鼎棋 3/17/2019
好!我想实现一个与图形相关的算法,所以我需要一个可变的集合来记录有效的下一个节点并在需要时删除它们。你教了我一个重要的概念,谢谢!