不可修改的地图(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对公共静态最终地图(“常量地图”)非常方便,并且还可以让您轻松制作由调用者提供给您的课程地图的“防御副本”。