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. Hanoi问题java解法

    用什么语言解法都差不多,思路都是一样,递归,这其中只要注重于开始和结果的状态就可以了,对于中间过程,并不需要深究.(我细细思考了一下,还是算了.=_=) 代码其实很简单注重的是思路. 问题描述:有一个 ...

  2. java工具类之Graphics

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

  3. UI内侧错题

    此题考察的是JQuery UI下的menu插件的使用,ui-menu表示菜单的外层容器,如果菜单包含图标,该元素会另外带一个 ui-menu-icons class.故A B选项错误.ui-menu- ...

  4. AC日记——丑数 codevs 1246

    1246 丑数 USACO  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description 对于一给定的素 ...

  5. Warning: strftime(): It is not safe to rely on the system's timezone settings.

    当运行程序时,会出现如下警告: Warning: strftime(): It is not safe to rely on the system's timezone settings. You a ...

  6. vs2015 编译时错误列表中没有错误,dll却没有生成出来

    最近发现vs2015的一个问题, 编译时,错误列表中没有错误,dll却没有生成出来,vs重启也无效 解决: 多次排查发现如果一个类库设置的是framework 4.0版本,但引用了framework4 ...

  7. [LeetCode] Self Crossing 自交

    You are given an array x of n positive numbers. You start at point (0,0) and moves x[0] metres to th ...

  8. [LeetCode] Odd Even Linked List 奇偶链表

    Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...

  9. [LeetCode] Minimum Window Substring 最小窗口子串

    Given a string S and a string T, find the minimum window in S which will contain all the characters ...

  10. 使用ANTS Performance Profiler&ANTS Memory Profiler工具分析IIS进程内存和CPU占用过高问题

    一.前言 最近一段时间,网站经常出现两个问题: 1.内存占用率一点点增高,直到将服务器内存占满. 2.访问某个页面时,页面响应过慢,CPU居高不下. 初步判断内存一点点增多可能是因为有未释放的资源一直 ...