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的内容还是可变的。见实例:

 1 public class UnmodifiableMap {
 2
 3     public static void main(String[] args) {
 4
 5         Map<String, Student> map = new HashMap<String, Student>();
 6         Student tom = new Student("tom", 3);
 7         map.put("tom", tom);
 8         map.put("jerry", new Student("jerry", 1));
 9
10         Map<String, Student> unmodifiableMap = Collections.unmodifiableMap(map);
11         // unmodifiableMap.put("tom", new Student("tom", 11));  // tag1
12         tom.setAge(11); // tag2
13         System.out.println(unmodifiableMap);
14     }
15
16 }
17
18 // mutable
19 class Student {
20     private String name;
21     private int age;
22
23     public Student(String name, int age) {
24         this.name = name;
25         this.age = age;
26     }
27
28     public String getName() {
29         return name;
30     }
31
32     public void setName(String name) {
33         this.name = name;
34     }
35
36     public int getAge() {
37         return age;
38     }
39
40     public void setAge(int age) {
41         this.age = age;
42     }
43
44     @Override
45     public String toString() {
46         return "Student{" +
47                 "name='" + name + '\'' +
48                 ", age=" + age +
49                 '}';
50     }
51 }

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

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

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

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

转载于:https://www.cnblogs.com/dreamysmurf/p/6253737.html

Collections.unmodifiableMap相关推荐

  1. [Google Guava] 2.3-强大的集合工具类:java.util.Collections中未包含的集合工具

    原文链接 译文链接 译者:沈义扬,校对:丁一 尚未完成: Queues, Tables工具类 任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collections包含的工具方法.G ...

  2. Java集合unmodifiableMap()方法及示例

    集合类unmodifiableMap()方法 (Collections Class unmodifiableMap() method) unmodifiableMap() method is avai ...

  3. Collections 工具类常见方法

    Collections 工具类常用方法: 排序 查找,替换操作 同步控制(不推荐,需要线程安全的集合类型时请考虑使用 JUC 包下的并发集合) 排序操作 void reverse(List list) ...

  4. 菜鸟学习笔记:Java提升篇4(容器4——Collections工具类、其他容器)

    菜鸟学习笔记:Java容器4--Collections工具类.其他容器 Collections工具类 容器其他知识点 队列Queue Enumeration接口 Hashtable Propertie ...

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

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

  6. 工具类 | 集合工具类Collections介绍

    前言 通过本文,你可以学习到 Collections 工具类的一些方法使用,在编码过程中都是非常实用的. 空集合 一个元素的集合 不可变集合 线程安全集合 批量增加 填充 交换位置 排序 逆序 随机排 ...

  7. 面试官:小伙汁,你画的SpringMVC请求处理过程是从网上抄的吧?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:Sicimike blog.csdn.net/Bai ...

  8. Spring Boot统一异常处理的拦截指南

    通常我们在Spring Boot中设置的统一异常处理只能处理Controller抛出的异常.有些请求还没到Controller就出异常了,而这些异常不能被统一异常捕获,例如Servlet容器的某些异常 ...

  9. javamap的用法_Java Map常用的几种用法。

    Java Map常用的几种用法. 通常,Map是由一组键值对组成的数据结构,每个键只能在映射中出现一次.这篇文章总结了有关如何使用Java Map及其实现的类的前9个常见问题解答.为了简单起见,我将在 ...

最新文章

  1. Kafka Eagle 源码解读
  2. 创业公司如何巧用工具提高团队生产力——豌豆荚创始人王俊煜讲述团队背后的“利器”...
  3. python读取excel画散点图-matplotlib两种画散点图的方式
  4. 【Android 安全】DEX 加密 ( Application 替换 | 分析 Service 组件中调用 getApplication() 获取的 Application 是否替换成功 )
  5. python的可变长参数
  6. Day 10: PhoneGap —— 开发手机应用如此简单
  7. python loads_python dumps和loads区别详解
  8. 抖音2020研究报告_抖音音乐发布2020抖音音乐生态数据报告
  9. ❤️震惊!人生苦短,我用python来玩田忌赛马❤️
  10. 漫话:如何给女朋友解释华为鸿蒙OS是怎样实现跨平台的?
  11. 苹果CMSV10绿色毛毛虫主题模板
  12. iOS获取、写入系统相册图片
  13. “社区之星”(社区核心贡献者)成长故事征集
  14. mysql中explain的详细解释
  15. 利用VS自带发布功能实现web项目快速部署
  16. 电视盒子刷linux树莓派,变废为宝二:闲置“树莓派”开发板秒变电视盒子!
  17. adjacent_find 的使用
  18. NVIDIA Jetson TK1学习与开发(三):图文详解Jetson TK1平台搭建
  19. python自动生成字幕_深度学习实现自动生成图片字幕
  20. 利用Javascript动态生成表格的小demo

热门文章

  1. ITK:创建三角形四边形网格
  2. ITK:概念检查是同一类型
  3. OpenCV ChArUco角的检测
  4. Qt Creator使用Qt Quick工具栏
  5. c++Interpolation search插值搜索的实现算法之二(附完整源码)
  6. QT绘制具有向下钻取效果的园饼图
  7. QT实现绘制3D基本形状
  8. C++案例-员工分组
  9. 经典C语言程序100例之八零
  10. C++技能的4种方法