今天阅读源码的时候,无意中看到了Collections.unmodifiableList的用法,因为以前没有这样做过,所以查询了他的API,是这样写的

public static <T> List<T> unmodifiableList(List<? extends T> list)

参数:list--这是一个不可修改视图是要返回的列表中。

返回值:在方法调用返回指定列表的不可修改视图。

1、用法探讨:

 1 public class CollectionsListDemo {
2 public static void main(String[] args) {
3
4 List<String> list = new ArrayList<String>();
5 list.add("aa");
6 list.add("bb");
7
8 System.out.println("初始化前: "+ list);
9
10 //实现 unmodifiable
11 List<Character> immutablelist = Collections.unmodifiableList(list);
12
13 //修改 list
14 immutablelist.add("zz");
15 }}
16
17 结果:
18
19 初始化前:: [aa, bb]
20
21 Exception in thread "main" java.lang.UnsupportedOperationException

2、继续追踪,到底什么场景遇到呢?重构是怎么写的的?

在《重构——改善既有代码的设计》一书中,有一种重构手法叫Encapsulate Collection  ,(封装集合),

定义是:让函数返回这个集合的副本,并在这个类中提供添加/移除集合的副本

为了演示该重构手法

这本书介绍的是:我们经常用集合,Collection,可能是Array,ArrayList,set,vector保存一组实例,这样的类通常也会提供针对该集合的取值与设值函数

但是集合的处理方式和其他种类略有不同,取值函数不应该返回集合本身,因为这会让用户得以修改集合的内容而集合拥有者去一无所知,这样会对用户 暴露过多的对象的内部结构信息。如果一个取值函数确实要返回多个值,他应该避免用户直接操作对象内保存的集合,并隐藏对象内与用户无关的的数据结构

此外,不应该为这个集合提供一个设置函数,但是应该提供对象内集合本身添加/删除的函数,这样,集合拥有者(对象)就可以控制集合元素的添加与删除

如果做到了上边的一点,集合就很好的封装起来,这样就降低了集合拥有者和用户之间的耦合度

常用到的做法:

(1)加入为集合添加/移除元素的函数

(2)将保存的集合的字段初始化一个空的集合

3、下面对上边的内容的例子介绍:

原来我这样写的:

 1 import java.util.List;
2
3 public class Student
4 {
5 private String userName ;
6
7 private List<String> courses ;
8
9
10 public Student (String userName , List<String> courses)
11 {
12 this.userName = userName;
13 this.courses = courses;
14 }
15
16 public String getUserName()
17 {
18 return userName ;
19 }
20
21 public void setUserName(String userName)
22 {
23 this.userName = userName;
24 }
25
26 public List<String> getCourses()
27 {
28 return courses ;
29 }
30
31 public void setCourses(List<String> courses)
32 {
33 this.courses = courses;
34 }
35
36
37
38 }

重构后,按照上面介绍的原则,这样重构:

 1 import java.util.ArrayList;
2 import java.util.Collections;
3 import java.util.List;
4
5 public class Student
6 {
7 private String userName ;
8
9 private List<String> courses ;
10
11 public Student (String userName , List<String> courses)
12 {
13 this.userName = userName;
14 this.courses = courses;
15 }
16
17 public String getUserName()
18 {
19 return userName ;
20 }
21
22 public void setUserName(String userName)
23 {
24 this.userName = userName;
25 }
26
27 public void addCourse(String course)
28 {
29 courses.add(course);
30 }
31
32 public boolean removeCourse(String course)
33 {
34 return courses .remove(courses );
35
36 }
37
38 public List<String> getCourses()
39 {
40 return Collections.unmodifiableList( courses);
41 }
42
43 public static void main(String[] args)
44 {
45 List<String> list = new ArrayList<String>();
46 list.add( "数学");
47 list.add( "语文");
48 Student s = new Student("lily" , list);
49
50 List<String> anotherList = s.getCourses();
51
52 /**
53 * throws java.lang.UnsupportedOperationException should replace with
54 * s.addCourse(String course)
55 */
56 anotherList.add( "英语");
57
58 // 不会走到这一步,因为上边抛出了异常
59 System. out.println("lily's course.length = " + s.getCourses().size());
60 }
61
62 }

4、总结

使用这种方法重构的意义:就好比我们网上购物一样,你可以往购物车添加自己想买的东西,但是商户不能在不通知顾客(我们)的情况下,就任意的添加商品,并修改商品的价格等,入口只能是一个,也就是在顾客手中。比喻可能不是很恰当,反正意思大概就是这样。

由Collections.unmodifiableList引发的重构的更多相关文章

  1. [ 转]Collections.unmodifiableList方法的使用与场景

    在公司接触到Collections.unmodifiableList(List<? extends T> list)) 觉得用法挺特殊的,所以学习了下,简单而言,看名字就知道,将参数中的L ...

  2. Collections.unmodifiableList()的使用与场景

    在<重构——改善既有代码的设计>一书中,有一种重构手法叫Encapsulate Collection(封装集群),为了演示该重构手法,我写了四个类,通过对比重构前后的代码,加深对这一重构手 ...

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

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

  4. 《Code Complete》ch.24 重构

    WHAT? 重构(refactoring),Martin Fowler将其定义为“在不改变软件外部行为的前提下,对其内部结构进行改变,使之更容易理解并便于修改”. WHY? 神话:一个管理很完善的软件 ...

  5. [Guava官方文档翻译] 7. Guava的Immutable Collection(不可变集合)工具 (Immutable Collections Explained)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3538666.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...

  6. Collections、Arrays 简明

    Collections : 它的出现给集合操作提供了更多的功能.这个类不需要创建对象,内部提供的都是静态方法. 一般方法 Collections. sort (list); list 集合进行元素的自 ...

  7. 【Java集合的详细研究1】Collections类常用方法总结

    1.sort(Collection)方法的使用(含义:对集合进行排序). 例:对已知集合c进行排序? public class Practice { public static void main(S ...

  8. Java:集合,Collections工具类用法

    Collections工具类提供了大量针对Collection/Map的操作,总体可分为四类,都为静态(static)方法: 1. 排序操作(主要针对List接口相关) reverse(List li ...

  9. Java中的集合框架-Collections和Arrays

    上一篇<Java中的集合框架-Map>把集合框架中的键值对容器Map中常用的知识记录了一下,本节记录一下集合框架的两个工具类Collections和Arrays 一,Collections ...

随机推荐

  1. 【LintCode】计算两个数的交集(一)

    问题分析: 既然返回值没有重复,我们不妨将结果放进set中,然后对两个set进行比较. 问题求解: public class Solution { /** * @param nums1 an inte ...

  2. 【BZOJ-4456】旅行者 分治 + 最短路

    4456: [Zjoi2016]旅行者 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 254  Solved: 162[Submit][Status] ...

  3. PhpStorm PHP开发神器

    链接:http://pan.baidu.com/s/1b4Vwjs 密码:c5uh

  4. poj3696 快速幂的优化+欧拉函数+gcd的优化+互质

    这题满满的黑科技orz 题意:给出L,要求求出最小的全部由8组成的数(eg: 8,88,888,8888,88888,.......),且这个数是L的倍数 sol:全部由8组成的数可以这样表示:((1 ...

  5. Java 中常用缓存Cache机制的实现

    所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例.这样做可以减少系统开销,提高系统效率. 所谓缓存,就是将程序或系统经常要调用的对象存在内存中 ...

  6. DLUTOJ1216

    题目大意是:给出N个正整数,其中至多有一个数只出现一次,其余的数都出现了两次.判断是否有某个数只出现一次,若有输出这个数,否则输出“-1”. 1<=N<=5000000 这道题的正解是用位 ...

  7. gnuplot conditional plotting: plot col A:col B if col C == x

    http://stackoverflow.com/questions/6564561/gnuplot-conditional-plotting-plot-col-acol-b-if-col-c-x H ...

  8. 深入JVM-锁与并发

    一.锁在Java虚拟机中的实现与优化 1.1 偏向锁 偏向锁是JDK 1.6 提出的一种锁优化方式.其核心思想是,如果程序没有竞争,则取消之前已经取得锁的线程同步操作.也就说,若某一锁被线程获取后,便 ...

  9. js003-基本概念

    js003-基本概念 3.1 语法 3.1.1 区分大小写 ECMAScript中的一切(变量.函数名和操作符)都是区分大小写的,并且不能用关键字作为函数名:如 typeof. 3.1.2 标识符 所 ...

  10. Linux中设置定期备份oracle数据库

    昨天装好了oracle,今天尝试一下自动备份,我这两天装linux和oracle的目的就是这个. 如果是sql server,定期备份可以利用sql server的management studio来 ...