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

觉得以下这篇文章写得很好,说 明了它的应用场景。

--------------------------------------------------------------------------------------

在《重构——改善既有代码的设计》一书中,有一种重构手法叫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方法的使用与场景的更多相关文章

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

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

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

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

  3. java中unmodifiableList方法的应用场景

    java对象中primitive类型变量可以通过不提供set方法保证不被修改,但对象的List成员在提供get方法后,就可以随意add.remove改变其结构,这不是希望的结果.网上看了下,发现Col ...

  4. 由Collections.unmodifiableList引发的重构

    原文  http://www.cnblogs.com/persist-confident/p/4516741.html 今天阅读源码的时候,无意中看到了Collections.unmodifiable ...

  5. Java中使用Collections.sort()方法对数字和字符串泛型的LIst进行排序

    在List的排序中常用的是Collections.sort()方法,可以对String类型和Integer类型泛型的List集合进行排序. 首先演示sort()方法对Integer类型泛型的List排 ...

  6. 用Java集合中的Collections.sort方法对list排序的两种方法

    用Collections.sort方法对list排序有两种方法第一种是list中的对象实现Comparable接口,如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  7. java中Collections.sort()方法实现集合排序

    1.Integer/String泛型的List进行排序 List <Integer> integerlist = new ArrayList<Integer>();   //定 ...

  8. java.util.Collections.synchronizedSet()方法的使用

    下面的例子显示java.util.Collections.synchronizedSet()方法的使用 package com.; import java.util.*; public class C ...

  9. java.util.Collections.copy()方法注意点

    今天发现单独的将一个ArrayList的对象添加到另外一个ArrayList的时候,总是源列表和目的列表相同的内存地址.原因如下: 偶然看到了Collections的copy(List desc,Li ...

随机推荐

  1. URAL1826. Minefield 题解

    原题: http://acm.timus.ru/problem.aspx?space=1&num=1826 1826. MinefieldTime limit: 0.5 secondMemor ...

  2. golang笔记——命令

    1.GO命令一览 GO提供了很多命令,包括打包.格式化代码.文档生成.下载第三方包等等诸多功能,我们可以通过在控制台下执行 go 来查看内置的所有命令 下面来逐个介绍,也可以详细参考 https:// ...

  3. web api 处理发送过来的文件(图片)

    using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.We ...

  4. Python XML解析(转载)

    Python XML解析 什么是XML? XML 指可扩展标记语言(eXtensible Markup Language). 你可以通过本站学习XML教程 XML 被设计用来传输和存储数据. XML是 ...

  5. Handler Should be static or leaks Occur?

    解决办法: public class SampleActivity extends Activity { /** * Instances of static inner classes do not ...

  6. EL表达式和JSTL

    EL相关概念JSTL一般要配合EL表达式一起使用,来实现在jsp中不出现java代码段.所以我们先来学习EL表达式 EL主要用于查找作用域中的数据,然后对它们执行简单操作:它不是编程语言,甚至不是脚本 ...

  7. loadrunner 学习笔记--AJAX(转)

    用loadrunner测试WEB程序的时候总是会碰到AJAX或者ActiveX实现的功能,而通常这些功能会包含很多客户端函数(一般为JavaScript).我们该如何处理?如果从功能实现的角度去考虑这 ...

  8. IoC模式

    1.依赖 依赖就是有联系,有地方使用到它就是有依赖它,一个系统不可能完全避免依赖.如果你的一个类或者模块在项目中没有用到它,恭喜你,可以从项目中剔除它或者排除它了,因为没有一个地方会依赖它.下面看一个 ...

  9. Codeforces 260 A - A. Laptops

    题目链接:http://codeforces.com/contest/456/problem/A 解题报告:有n种电脑,给出每台电脑的价格和质量,要你判断出有没有一种电脑的价格小于另一种电脑但质量却大 ...

  10. BZOJ2466——[中山市选]树

    1.题目大意:给你一棵树,树的每个节点都有一个权值,是0或1,最开始都是0,你可以做一种修改操作,就是把一个节点和它相邻的 节点的权值取反,问最少几次修改能把所有节点的权值变得都是1,最多100个节点 ...