不可修改的地图(Java Collections)vs ImmutableMap(Google)

上下文

我需要返回一个引用到我用于数据caching的地图,我想确保没有人可以修改他们的引用。

我在网上看到很多关于UnmodifiableMap和ImmutableMap的引用,但是我没有看到任何比较/对比的东西。 我认为有一个很好的理由,谷歌/番石榴创造了自己的版本 – 有人可以告诉我它是什么?

一个不可修改的地图可能会改变。 它只是一个可修改的地图上的一个视图 ,并且通过不可修改的地图可以看到底图的变化。 不可修改的映射只能防止那些只能引用不可修改视图的修改:

Map<String, String> realMap = new HashMap<String, String>(); realMap.put("A", "B"); Map<String, String> unmodifiableMap = Collections.unmodifiableMap(realMap); // This is not possible: It would throw an // UnsupportedOperationException //unmodifiableMap.put("C", "D"); // This is still possible: realMap.put("E", "F"); // The change in the "realMap" is now also visible // in the "unmodifiableMap". So the unmodifiableMap // has changed after it has been created. unmodifiableMap.get("E"); // Will return "F". 

与此相反,番石榴的ImmutableMap是不可变的 :它是给定地图的真实副本 ,没有人可以以任何方式修改这个ImmutableMap。

更新

正如在评论中指出的那样,也可以使用标准API创build不可变映射

 Map<String, String> immutableMap = Collections.unmodifiableMap(new LinkedHashMap<String, String>(realMap)); 

这将在给定映射的真实副本上创build一个不可修改的视图,因此可以很好地模拟ImmutableMap的特性,而不必将相关性添加到Guava。

看看ImmutableMap JavaDoc: doc

有关于那里的信息:

与Collections.unmodifiableMap(java.util.Map)不同,它是一个可以改变的单独映射的视图,ImmutableMap的一个实例包含自己的数据,并且永远不会改变。 ImmutableMap对公共静态最终地图(“常量地图”)非常方便,并且还可以让您轻松制作由调用者提供给您的课程地图的“防御副本”。

Guava文档

JDK提供了Collections.unmodifiableXXX方法,但是在我们看来,这些方法很笨拙和冗长; 不愉快的地方使用任何你想使防御性副本不安全:返回的集合是真正的不变的,如果没有人对原始集合的引用效率低下:数据结构仍然具有可变集合的所有开销,包括并发修改检查,额外的空间散列表等

ImmutableMap不接受null值,而Collections.unmodifiableMap()却可以。 另外它在施工后不会改变,而UnmodifiableMap可能。 从JavaDoc:

一个不可变的,基于散列的Map,具有可靠的用户指定迭代次序。 不允许空键或值。

与Collections.unmodifiableMap(java.util.Map)不同,它是一个可以改变的单独映射的视图,ImmutableMap的一个实例包含自己的数据,并且永远不会改变。 ImmutableMap对公共静态最终地图(“常量地图”)非常方便,并且还可以让您轻松制作由调用者提供给您的课程地图的“防御副本”。