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的同时,尽量让其中的内容实现为不可变对象。

Collections.unmodifiableMap的更多相关文章

  1. java.util.Collections.unmodifiableMap 示例

    1. 概述 public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m) ...

  2. Collections.unmodifiableMap,Collections.unmodifiableList,Collections.unmodifiableSet作用及源码解析

    在文章:Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析中mybatis的源码中用到了Collections.unmodifiableList方法,其实还有unmodifiabl ...

  3. Collections.unmodifiableMap(Map map)

    public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)返回指定映射 ...

  4. 操作集合的工具类:Collections

    Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类提供了大量方法对集合进行排序.查询和修改等操作,还提供了将集合对象置为不可变.对集合对象实现同步控制等方法 ...

  5. JAVA基础知识之Collections工具类

    排序操作 Collections提供以下方法对List进行排序操作 void reverse(List list):反转 void shuffle(List list),随机排序 void sort( ...

  6. Java常用类(五)之集合工具类Collections

    前言 Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类提供了大量方法对集合进行排序.查询和修改等操作, 还提供了将集合对象置为不可变.对集合对象实现同步控 ...

  7. linkin大话数据结构--Collections类

    操作集合的工具类:Collections Collections 是一个操作 Set.List 和 Map 等集合的工具类.Collections 中提供了大量方法对集合元素进行排序.查询和修改等操作 ...

  8. Java集合框架(六)—— Collections工具类

    操作集合的工具类Collections Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类里提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了将集 ...

  9. 集合-强大的集合工具类:java.util.Collections中未包含的集合工具

    任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collections包含的工具方法.Guava沿着这些路线提供了更多的工具方法:适用于所有集合的静态方法.这是Guava最流行和成熟 ...

随机推荐

  1. Mybatis 查不到数据,总是返回Null

    mybatis突然查不到数据,查询返回的都是Null,但是 select count(*) from xxx查询数量,返回却是正常的. Preparing: SELECT id,a9004,a9005 ...

  2. Git权威指南 书摘

    ##$ git add welcome.txtwarning: LF will be replaced by CRLF in welcome.txt.The file will have its or ...

  3. RabbitMQ调试与测试工具-v1.0.1 -提供下载测试与使用

    最近几天在看RabbitMQ,所以发了两天时间写了一个调试和测试工具.方便使用. 下载地址:RabbitMQTool-V1.0.1.zip

  4. [No000098]SVN学习笔记5-分支,合并,属性,补丁,锁,分支图

    行结束符和空白选项 在项目的生命周期中,有时可能会将行结束符由 CRLF 改为 LF,或者修改一段代码的缩进.不幸的是这样将会使大量的代码行被标记为已修改,尽管代码本身并没有被修改.这里列出的选项将会 ...

  5. [LeetCode] Longest Common Prefix 最长共同前缀

    Write a function to find the longest common prefix string amongst an array of strings. 这道题让我们求一系列字符串 ...

  6. go interface

    //所有的结构体 都实现了空接口 //接口类型转换 结构体变量 = 接口名(实现接口的结构体变量) 只能高级转为低级 就是转前的接口中方法在转后接口中都有实现 package main import ...

  7. Ext分页实现(前台与后台)

    Ext分页实现(前台与后台)Spring+Mybatis 一.项目背景 关于Ext的分页网上有很多博客都有提到,但是作为Ext新手来说,并不能很容易的在自己的项目中得以应用.因为,大多数教程以及博客基 ...

  8. ActiveMQ安全配置

    1.activeMQ管理后台用户名.密码的设置 管理后台地址http://localhost:8161/admin 默认用户名密码admin admin 端口默认是8161,且服务采用的是服务器,所以 ...

  9. ubuntu中pycharm安装激活第二种方法的密钥

    43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNza WduZWVOYW1lIjoi ...

  10. vuex 初体验

    vuex是vue的状态管理工具,vue进阶从es6和npm开始,es6推荐阮一峰大神的教程. vuex学习从官方文档和一个记忆小游戏开始.本着兴趣为先的原则,我先去试玩了一把-->. Vuex ...