高效“修改”不可变映射
2022-09-04 22:57:57
我们目前正在使用Guava作为其不可变的集合,但我惊讶地发现他们的地图没有方法可以轻松地创建新地图,只需稍作修改。最重要的是,他们的构建器不允许为键分配新值或删除键。
因此,如果我只想修改一个值,我希望能够执行以下操作:
ImmutableMap<Guid, ImmutableMap<String, Integer>> originalMap = /* get the map */;
ImmutableMap<Guid, ImmutableMap<String, Integer>> modifiedMap =
originalMap.cloneAndPut(key, value);
以下是番石榴期待我做的事情:
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 */
通过这样做,我得到了一个新的地图副本,其中包含我想要的修改。原始副本未被触及,我将使用原子引用将该内容放回原处,因此整个设置是线程安全的。
它只是很慢。
这里有很多浪费的复制工作。假设地图中有 1,024 个存储桶。这是1,023个桶,你不必要地再次创建(每个桶也两次),而你可以按原样使用这些不可变的桶,只克隆其中一个。
所以我猜:
有没有一种番石榴实用方法埋在什么地方用于这种事情?(它不在 Maps 或 ImmutableMap.Builder 中。
有没有其他Java库可以正确处理这种事情?我的印象是Clojure在引擎盖下有这种东西,但我们还没有准备好切换语言......