Scala 不可变映射,何时变为可变?

标签 scala map immutability mutable use-case

我目前的用例非常简单,可变或不可变 Map 都可以解决问题。

有一个采用不可变 Map 的方法,然后调用一个采用不可变 Map 的第 3 方 API 方法

def doFoo(foo: String = "default", params: Map[String, Any] = Map()) {

  val newMap = 
    if(someCondition) params + ("foo" -> foo) else params

  api.doSomething(newMap)
}

有问题的 Map 通常很小,最多可能有一个嵌入的案例类实例列表,最多几千个条目。因此,再次假设在这种情况下不可变几乎没有影响(即通过 newMap val 副本基本上具有 Map 的 2 个实例)。

尽管如此,它还是让我有点烦,复制 map 只是为了得到一张新 map ,上面有几个 k->v 条目。

我可以去可变和 params.put("bar", bar)等我想添加的条目,然后 params.toMap为 api 调用转换为不可变,这是一个选项。但随后我必须导入并传递可变映射,与使用 Scala 的默认不可变映射相比,这有点麻烦。

那么,在不可变 Map 上使用可变 Map 是合理/良好实践的一般准则是什么?

谢谢

编辑
因此,似乎对不可变映射执行添加操作需要几乎恒定的时间,这证实了 @dhg 和 @Nicolas 的断言,即未制作完整副本,这解决了所呈现的具体案例的问题。

最佳答案

根据不可变的 Map 实现,添加一些条目实际上可能不会复制整个原始 Map。这是不可变数据结构方法的优点之一:Scala 会尽量避免复制。

这种行为最容易通过 List 看到。 .如果我有一个 val a = List(1,2,3) ,然后该列表存储在内存中。但是,如果我在前面添加一个附加元素,例如 val b = 0 :: a ,我确实得到了一个新的 4 元素 List返回,但 Scala 没有复制原始列表 a .相反,我们只是创建了一个新链接,命名为 b ,并给它一个指向现有列表的指针 a .

您也可以为其他类型的集合设想这样的策略。例如,如果我向 Map 添加一个元素,集合可以简单地包装现有 map ,在需要时回退到它,同时提供一个 API,就好像它是一个 Map .

关于Scala 不可变映射,何时变为可变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10141654/

相关文章:

java - 我该如何改进这个 Point 类

scala - 为什么在 RHS 而不是 LHS 中定义类型?

java - Akka是否适合瞬时网络覆盖的系统?

algorithm - 我有一个集合,其中包含每个集合元素的值,并且我希望按值将元素尽可能均匀地分布在 N block 上

r - R中的动画gadm map

c++ - C++ 中作为类成员的静态映射

scala - 在 Scala json4s 中获取一个字段

C++ STL map.find() 找不到我的东西

python卡住数据类不可变对象(immutable对象).__setattr__

javascript - 在没有索引或唯一标识符的情况下 react : How to modify an array-based state,?