java - 有效地 "modifying"一个 ImmutableMap

标签 java map immutability guava

我们目前正在将 Guava 用于其不可变集合,但我惊讶地发现他们的 map 没有方法可以轻松创建只需稍作修改的新 map 。最重要的是,他们的构建器不允许为键分配新值或删除键。

因此,如果我只想修改一个值,这就是我希望能够执行的操作:

ImmutableMap<Guid, ImmutableMap<String, Integer>> originalMap = /* get the map */;
ImmutableMap<Guid, ImmutableMap<String, Integer>> modifiedMap =
    originalMap.cloneAndPut(key, value);

这是 Guava 希望我做的事情:

ImmutableMap<Guid, ImmutableMap<String, Integer>> originalMap = /* get the map */;
Map<Guid, ImmutableMap<String, Integer>> mutableCopy = new LinkedHashMap<>(originalMap);
mutableCopy.put(key, value);
originalMap = ImmutableMap.copyOf(mutableCopy);
/* put the map back */

通过这样做,我得到了一份 map 的新副本,并进行了我想要的修改。原始副本未受影响,我将使用原子引用将其放回原处,以便整个设置是线程安全的。

它只是很慢。

这里隐藏着大量无用的复制。假设 map 中有 1,024 个桶。那是 1,023 个存储桶,您无需重新创建这些存储桶(每个存储桶也创建两次),而您本可以按原样使用这些不可变的存储桶并仅克隆其中一个。

所以我猜:

  1. 是否有针对此类事情埋藏在某处的 Guava 实用方法? (它不在 map 或 ImmutableMap.Builder 中。)

  2. 是否有任何其他 Java 库可以正确处理此类问题?我的印象是 Clojure 在幕后有这种东西,但我们还没有准备好切换语言......

最佳答案

有点意外map of Functional Java像 Guava 一样可变。正如我所料,该列表是不可变的。

Google 搜索“持久集合 java”,出现:pcollections。有一个 Map implementation .

在实际使用任何其他实现之前,我会针对 Guava 对内存和性能特征进行基准测试。如果它仍然更好,我不会感到惊讶。

关于java - 有效地 "modifying"一个 ImmutableMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9091449/

相关文章:

c++ - 是否可以将STL复制功能与 map 一起使用

perl - 在 Perl 中,如何使用 grep 实现 map ?

java - 可变类还是不可变类?

Java:不可变类的伪setter方法

java - BindResult hasErrors方法未显示

java - 使用 Java 枚举

java - JLabel:异步加载 HTML 图像

java - 相机 Intent 在某些设备上不起作用

java - 如何在 Java 中生成 map ?

Spring MVC 3 - 将 'immutable' 对象绑定(bind)到表单