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. Caffe Python MemoryDataLayer Segmentation Fault

    转载请注明出处,楼燚(yì)航的blog,http://home.cnblogs.com/louyihang-loves-baiyan/ 因为利用Pyhon来做数据的预处理比较方便,因此在data_l ...

  2. java工具类之Graphics

    利用重写paint()方法绘画出一个坐标轴: package huaxian; import java.awt.Color; import java.awt.FlowLayout; import ja ...

  3. Java程序设计之Constructor

    插入段代码,下次回忆吧. 先新建一个Person类,代码如下: public class Person { private String name ; private int age; public ...

  4. 分布式监控系统Zabbix-3.0.3-完整安装记录(7)-使用percona监控MySQL

    前面已经介绍了分布式监控系统Zabbix-3.0.3-完整安装记录(2)-添加mysql监控,但是没有提供可以直接使用的Key,太过简陋,监控效果不佳.要想更加仔细的监控Mysql,业内同学们都会选择 ...

  5. spring.net 框架分析(三)ContextRegistry.GetContext()

    我们通过ContextRegistry.GetContext()建立了一个IApplicationContext得实例,那么这个实例具体是怎么建立的了. 我们来分析一下容器实例建立的过程: 我们在配置 ...

  6. 如何在 Java 中正确使用 wait, notify 和 notifyAll(转)

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...

  7. [LeetCode] Unique Word Abbreviation 独特的单词缩写

    An abbreviation of a word follows the form <first letter><number><last letter>. Be ...

  8. javascript正则表达式(RegExp)简述

    首先我们来思考以下两个个场景 我们使用window操作系统,有时候需要找一个文件,刚刚好这个文件我不知道放哪里去了,这个时候我们该怎么办呢? 我们使用word写论文的时候,不小心将"订价&q ...

  9. Maven学习笔记

    1.Maven安装 Maven和ant同为apache出版的构建工具,与gradle是一类东西,与C语言中的make是同一类产品.从apache官网上下载maven的zip安装包,解压即可使用,需要把 ...

  10. Office2016打开doc字符间距过小

    缺少字体.........装上就行,放到windows/fonts目录下,自动安装了