考虑使用可变映射来跟踪出现/计数的简单问题,即:
val counts = collection.mutable.Map[SomeKeyType, Int]()
我目前增加计数的方法是:
counts(key) = counts.getOrElse(key, 0) + 1
// or equivalently
counts.update(key, counts.getOrElse(key, 0) + 1)
这不知何故感觉有点笨拙,因为我必须两次指定密钥。在性能方面,我还希望它key
必须在地图中定位两次,我想避免这种情况。Int
有趣的是,如果提供一些修改自身的机制,就不会出现这种访问和更新问题。例如,更改为提供函数Int
的类将允许:Counter
increment
// not possible with Int
counts.getOrElseUpdate(key, 0) += 1
// but with a modifiable counter
counts.getOrElseUpdate(key, new Counter).increment
不知何故,我总是期望具有可变映射的以下功能(有点类似于transform
但不返回新集合并且在具有默认值的特定键上):
// fictitious use
counts.updateOrElse(key, 0, _ + 1)
// or alternatively
counts.getOrElseUpdate(key, 0).modify(_ + 1)
但是据我所知,这样的功能不存在。一般来说(性能和语法方面)有这种f: A => A
就地修改的可能性不是很有意义吗?可能我只是在这里遗漏了一些东西......我想必须有一些更好的解决方案来解决这个问题,使这样的功能变得不必要?
更新:
我应该澄清一下我知道withDefaultValue
但问题仍然存在:执行两次查找仍然比一次慢两倍,无论它是否是 O(1) 操作。坦率地说,在许多情况下,我非常乐意实现因子 2 的加速。显然,修改闭包的构造通常可以移到循环之外,所以恕我直言,与运行不必要的操作两次。