Collections.unmodifiableMap
1. Collections.unmodifiableMap 是什么?
Java的官方解释:
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
翻译过来就是:该方法返回了一个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的更多相关文章
- java.util.Collections.unmodifiableMap 示例
1. 概述 public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m) ...
- Collections.unmodifiableMap,Collections.unmodifiableList,Collections.unmodifiableSet作用及源码解析
在文章:Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析中mybatis的源码中用到了Collections.unmodifiableList方法,其实还有unmodifiabl ...
- Collections.unmodifiableMap(Map map)
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)返回指定映射 ...
- 操作集合的工具类:Collections
Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类提供了大量方法对集合进行排序.查询和修改等操作,还提供了将集合对象置为不可变.对集合对象实现同步控制等方法 ...
- JAVA基础知识之Collections工具类
排序操作 Collections提供以下方法对List进行排序操作 void reverse(List list):反转 void shuffle(List list),随机排序 void sort( ...
- Java常用类(五)之集合工具类Collections
前言 Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类提供了大量方法对集合进行排序.查询和修改等操作, 还提供了将集合对象置为不可变.对集合对象实现同步控 ...
- linkin大话数据结构--Collections类
操作集合的工具类:Collections Collections 是一个操作 Set.List 和 Map 等集合的工具类.Collections 中提供了大量方法对集合元素进行排序.查询和修改等操作 ...
- Java集合框架(六)—— Collections工具类
操作集合的工具类Collections Java提供了一个操作Set.List和Map等集合的工具类:Collections,该工具类里提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了将集 ...
- 集合-强大的集合工具类:java.util.Collections中未包含的集合工具
任何对JDK集合框架有经验的程序员都熟悉和喜欢java.util.Collections包含的工具方法.Guava沿着这些路线提供了更多的工具方法:适用于所有集合的静态方法.这是Guava最流行和成熟 ...
随机推荐
- Mybatis 查不到数据,总是返回Null
mybatis突然查不到数据,查询返回的都是Null,但是 select count(*) from xxx查询数量,返回却是正常的. Preparing: SELECT id,a9004,a9005 ...
- Git权威指南 书摘
##$ git add welcome.txtwarning: LF will be replaced by CRLF in welcome.txt.The file will have its or ...
- RabbitMQ调试与测试工具-v1.0.1 -提供下载测试与使用
最近几天在看RabbitMQ,所以发了两天时间写了一个调试和测试工具.方便使用. 下载地址:RabbitMQTool-V1.0.1.zip
- [No000098]SVN学习笔记5-分支,合并,属性,补丁,锁,分支图
行结束符和空白选项 在项目的生命周期中,有时可能会将行结束符由 CRLF 改为 LF,或者修改一段代码的缩进.不幸的是这样将会使大量的代码行被标记为已修改,尽管代码本身并没有被修改.这里列出的选项将会 ...
- [LeetCode] Longest Common Prefix 最长共同前缀
Write a function to find the longest common prefix string amongst an array of strings. 这道题让我们求一系列字符串 ...
- go interface
//所有的结构体 都实现了空接口 //接口类型转换 结构体变量 = 接口名(实现接口的结构体变量) 只能高级转为低级 就是转前的接口中方法在转后接口中都有实现 package main import ...
- Ext分页实现(前台与后台)
Ext分页实现(前台与后台)Spring+Mybatis 一.项目背景 关于Ext的分页网上有很多博客都有提到,但是作为Ext新手来说,并不能很容易的在自己的项目中得以应用.因为,大多数教程以及博客基 ...
- ActiveMQ安全配置
1.activeMQ管理后台用户名.密码的设置 管理后台地址http://localhost:8161/admin 默认用户名密码admin admin 端口默认是8161,且服务采用的是服务器,所以 ...
- ubuntu中pycharm安装激活第二种方法的密钥
43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNza WduZWVOYW1lIjoi ...
- vuex 初体验
vuex是vue的状态管理工具,vue进阶从es6和npm开始,es6推荐阮一峰大神的教程. vuex学习从官方文档和一个记忆小游戏开始.本着兴趣为先的原则,我先去试玩了一把-->. Vuex ...