UnmodifiableMap(Java Collections)与ImmutableMap(Google)

时间:2014-03-25 13:49:06

标签: java collections map guava

上下文

我需要返回对我用于数据缓存的地图的引用,并且我想确保没有人可以修改它们的引用。

问题

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

4 个答案:

答案 0 :(得分:162)

不可修改的地图可能仍会发生变化。它只是可修改地图上的视图,并且通过不可修改的地图可以看到支持地图中的更改。不可修改的映射仅阻止对仅具有对不可修改视图的引用的人的修改:

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". 

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

更新

正如在comment中指出的那样,也可以使用标准API使用

创建不可变地图
Map<String, String> immutableMap = 
    Collections.unmodifiableMap(new LinkedHashMap<String, String>(realMap)); 

这将在给定地图的真实副本上创建一个不可修改的视图,因此可以很好地模拟ImmutableMap的特征,而无需将依赖项添加到Guava。

答案 1 :(得分:8)

查看ImmutableMap JavaDoc:doc

有关于那里的信息:

  

与Collections.unmodifiableMap(java.util.Map)不同,它是一个可以更改的单独地图的视图,ImmutableMap的实例包含自己的数据,永远不会更改。 ImmutableMap方便公共静态最终地图(&#34;常量地图&#34;),也可以让你轻松制作一个防御性副本&#34;由来电者提供给您班级的地图。

答案 2 :(得分:2)

Guava Documentation

  

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

答案 3 :(得分:2)

ImmutableMap不接受null值,而Collections.unmodifiableMap()则接受UnmodifiableMap值。此外,它在构造后永远不会改变,而{{1}}可能会改变。来自JavaDoc:

  

基于散列的不可变Map,具有可靠的用户指定迭代顺序。不允许使用null键或值。

     

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