1. Collections.unmodifiableMap 是什么?

Java的官方解释:

public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
Returns an unmodifiable view of the specified map. This method allows modules to provide users with "read-only" access to internal maps. Query operations on the returned map "read through" to the specified map, and attempts to modify the returned map, whether direct or via its collection views, result in an UnsupportedOperationException.

翻译过来就是:该方法返回了一个map的不可修改的视图umap, 为用户提供了一种生成只读容器的方法。如果尝试修改该容器umap, 将会抛出UnsupportedOperationException异常。

2. Collections.unmodifiableMap 能做什么?

在《重构-改善既有代码逻辑》一书中提到了封装集合的功能(Encapsulate Collection)。

我们在类中经常需要返回一个集合,比如mapA。如果直接返回成员变量mapA本身的话,相当于对外暴露了集合的引用,外部就可以随意修改该对象的集合,该对象可能对修改都一无所知,属性却发生了变化。

一种解决方法,就是将该集合修饰为private, 在返回集合的方法中采用Collections.unmodifiableMap(mapA),返回mapA的一个不可变的副本。且该方法要比我们自己去复制一个副本效率要高。

3. Collections.unmodifiableMap 构造的map真的不可修改吗?

遗憾的是该结论并不总是成立。对于map<key, value>中的内容value, unmodifiableMap仅仅保证的是它的引用不能被修改,如果value对应的是一个可变对象,那么该unmodifiableMap的内容还是可变的。见实例:

 public class UnmodifiableMap {

     public static void main(String[] args) {

         Map<String, Student> map = new HashMap<String, Student>();
Student tom = new Student("tom", 3);
map.put("tom", tom);
map.put("jerry", new Student("jerry", 1)); Map<String, Student> unmodifiableMap = Collections.unmodifiableMap(map);
// unmodifiableMap.put("tom", new Student("tom", 11)); // tag1
tom.setAge(11); // tag2
System.out.println(unmodifiableMap);
} } // mutable
class Student {
private String name;
private int age; public Student(String name, int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

代码中Student 对象是可变对象。在tag1处,尝试更换为另一个对象,引用发生了变化,会抛出UnsupportedOperationException异常。unmodifiableMap阻止了对其的修改

但如果引用不变,见tag2处,还是tom, 但对该对象内容作了修改,unmodifiableMap并未阻止该行为。unmodifiableMap的内容变为了

{jerry=Student{name='jerry', age=1}, tom=Student{name='tom', age=11}}

所以为了线程安全,在使用Collections.unmodifiableMap的同时,尽量让其中的内容实现为不可变对象。

最新文章

  1. 自定义RatingBar,不同分辨率屏幕下图片拉伸或者显示不完整问题解决
  2. GOF业务场景的设计模式-----责任链模式
  3. js文字滚动
  4. PHP获取日期
  5. reactjs入门到实战(五)---- props详解
  6. Windows 调色板
  7. BZOJ2879 [Noi2012]美食节
  8. javascript设计模式--状态模式(State)
  9. 学习 .net 的一些主要网站
  10. BZOJ 2754([SCOI2012]喵喵叫的星球-统计序列的后缀阵列中子序列出现次数)
  11. KTV2
  12. -_-#【JS】isFinite
  13. C语言的输入输出操作函数小结
  14. 存储过程学习笔记(SQL数据库
  15. 中兴iptv机顶盒破解教程图文:亲测中兴B760EV3、B860A、B860AV1.1完美安装应用!非ttl破解![转]
  16. sublime3安装ctags追踪插件
  17. IOS中的用户安全
  18. How can R and Hadoop be used together?
  19. spring cloud学习(一) 服务注册
  20. SourceTree 代码库管理工具

热门文章

  1. SQL分隔字符串
  2. SQL Server数据库性能优化技巧
  3. HTML5全屏(Fullscreen)API详细介绍
  4. Duplicate entry &#39;javajavajav&#39; for key &#39;username&#39;
  5. C++基本数据类型总结
  6. 【WPF】释放图像资源, [删除时报另一进程占用]
  7. [转]ExtJS Grid 分页时保持选中的简单实现方法
  8. ios app 企业帐号发布,在浏览器中直接点击链接下载安装
  9. caffe代码调试小结
  10. vector定义初始化