Collections.unmodifiableList()的使用与场景
在《重构——改善既有代码的设计》一书中,有一种重构手法叫Encapsulate Collection
(封装集群),为了演示该重构手法,我写了四个类,通过对比重构前后的代码,加深对
这一重构手法的理解。
类Student有一ArrayList属性,如果没有阅读《重构——改善既有代码的设计》一书,
很多人可能会像我一样,如下设计类Student。但是,如果通过Student.getCourses()
获得对ArrayList属性引用后,就可以任意为Student对象添加“课程”,而Student对象
对此一无所知,这不符合面向对象编程的习惯。
package com.readonlylist;
import java.util.ArrayList;
public class Student
{
private String name;
private ArrayList<String> courses;
public Student(String name, ArrayList<String> courses)
{
this.name = name;
this.courses = courses;
}
public ArrayList<String> getCourses()
{
return courses;
}
public void setCourses(ArrayList<String> courses)
{
this.courses = courses;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}
package com.readonlylist;
import java.util.ArrayList;
public class Test
{
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add("001");
list.add("002");
Student s = new Student("Tom", list);
ArrayList<String> anotherList = s.getCourses();
anotherList.add("999");
System.out.println("Tom's course.length = " + s.getCourses().size());
}
}
重构后的Student类如下所示:
package com.readonlylist;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Student1
{
private String name;
private ArrayList<String> courses;
public Student1(String name, ArrayList<String> courses)
{
this.name = name;
this.courses = courses;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public void addCourse(String course)
{
courses.add(course);
}
public String removeCourse(String course)
{
boolean removed = courses.remove(courses);
if (removed)
{
return course;
}
else
{
return null;
}
}
public List<String> getCourses()
{
return Collections.unmodifiableList(courses);
}
}
package com.readonlylist;
import java.util.List;
import java.util.ArrayList;
public class Test1
{
public static void main(String[] args)
{
ArrayList<String> list = new ArrayList<String>();
list.add("001");
list.add("002");
Student1 s = new Student1("Tom", list);
List<String> anotherList = s.getCourses();
/**
* throws java.lang.UnsupportedOperationException
* should replace with s.addCourse(String course)
*/
anotherList.add("999");
// never reached
System.out.println("Tom's course.length = " + s.getCourses().size());
}
}
重构后,Student1类,仅对外提供的getCourses()方法,而没有setCourses()方法,而且
通过getCourses()方法获得的courses是“只读的”,如果你试图向其添加一个新课程,则
抛出java.lang.UnsupportedOperationException。你必须通过Student1.addCourse()来
向特定的Student1对象添加一个新课程。就好像,你必须让顾客自己向购物车里放食物,
而不能在顾客毫不知情下,偷偷向其购物车里放食物。
真是万物皆通情理啊:)
--------------------------------------------------------------------------------------
原文地址:http://hi.baidu.com/onejava/blog/item/10388f2b77d340fae6cd4091.html
Collections.unmodifiableList()的使用与场景的更多相关文章
- [ 转]Collections.unmodifiableList方法的使用与场景
在公司接触到Collections.unmodifiableList(List<? extends T> list)) 觉得用法挺特殊的,所以学习了下,简单而言,看名字就知道,将参数中的L ...
- 由Collections.unmodifiableList引发的重构
原文 http://www.cnblogs.com/persist-confident/p/4516741.html 今天阅读源码的时候,无意中看到了Collections.unmodifiable ...
- java中unmodifiableList方法的应用场景
java对象中primitive类型变量可以通过不提供set方法保证不被修改,但对象的List成员在提供get方法后,就可以随意add.remove改变其结构,这不是希望的结果.网上看了下,发现Col ...
- Collections.unmodifiableMap,Collections.unmodifiableList,Collections.unmodifiableSet作用及源码解析
在文章:Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析中mybatis的源码中用到了Collections.unmodifiableList方法,其实还有unmodifiabl ...
- [Guava官方文档翻译] 7. Guava的Immutable Collection(不可变集合)工具 (Immutable Collections Explained)
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3538666.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...
- Collections、Arrays 简明
Collections : 它的出现给集合操作提供了更多的功能.这个类不需要创建对象,内部提供的都是静态方法. 一般方法 Collections. sort (list); list 集合进行元素的自 ...
- 【Java集合的详细研究1】Collections类常用方法总结
1.sort(Collection)方法的使用(含义:对集合进行排序). 例:对已知集合c进行排序? public class Practice { public static void main(S ...
- Java:集合,Collections工具类用法
Collections工具类提供了大量针对Collection/Map的操作,总体可分为四类,都为静态(static)方法: 1. 排序操作(主要针对List接口相关) reverse(List li ...
- Java中的集合框架-Collections和Arrays
上一篇<Java中的集合框架-Map>把集合框架中的键值对容器Map中常用的知识记录了一下,本节记录一下集合框架的两个工具类Collections和Arrays 一,Collections ...
随机推荐
- 重新开始学习javase_集合_Set
一,Set之HashSet(转:http://blog.csdn.net/zheng0518/article/details/42197337) 1. HashSet概述: HashSet实现S ...
- [转]Java远程方法调用
Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序可以调用远 ...
- #include<unistd.h>存在linux中,含有系统服务的函数
#include<unistd.h> linux标准库#include <unistd.h>与windows的#include <windows.h>(C语言开发) ...
- 九度OJ 1025 最大报销额(01背包)
题目1025:最大报销额 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2683 解决:608 题目描述: 现有一笔经费可以报销一定额度的发票.允许报销的发票类型包括买图书(A类).文具( ...
- LINUX系统安装MYSQL命令,纯手打
1.下载安装包 wget http://cdn.mysql.com/archives/mysql-5.6/mysql-5.6.26-linux-glibc2.5-x86_64.tar.gz 2. ...
- JavaScript设计模式之单例模式
一.单例模式概念 单例就是保证一个类只有一个实例,实现方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象.在JavaScript里,单例作为一个 ...
- 使用bootstrap模态框实现浮动层
authour: 陈博益 updatetime: 2015-04-22 06:52:15 friendly link: http://v3.bootcss.com/javascript/#modals ...
- 【JavaScript】JavaScript教程之------------------JavaScript实现
JavaScript的核心ECMAScript描述了该语言的语法与基本对象: DOM描述了处理网页内容的方法和接口: BOM描述了与浏览器进行交互的方法和接口: 完整的JavaScript实现是由以下 ...
- 分析智能卡的ATR格式
一些例子 NXP 080=========3b f8 T0 Y1 = 0xF(TA1, TB1, TC1, TD1), K = 813 TA1 F = 0x1(Fi = 372, Fmax = 5 ...
- BZOJ1596: [Usaco2008 Jan]电话网络
1596: [Usaco2008 Jan]电话网络 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 513 Solved: 232[Submit][S ...