博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[ 转]Collections.unmodifiableList方法的使用与场景
阅读量:6256 次
发布时间:2019-06-22

本文共 2963 字,大约阅读时间需要 9 分钟。

 

在公司接触到Collections.unmodifiableList(<? 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对象添加一个新课程。就好像,你必须让顾客自己向购物车里放食物,
而不能在顾客毫不知情下,偷偷向其购物车里放食物。

真是万物皆通情理啊:)

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

原文地址:

转载于:https://www.cnblogs.com/ryq2014/p/5258502.html

你可能感兴趣的文章
c#中的常用ToString()方法总结
查看>>
ajax五,jsonp跨域的本质
查看>>
调用打印机打印
查看>>
poj1742
查看>>
js--val()比较少用的用法
查看>>
bzoj2002: [Hnoi2010]Bounce 弹飞绵羊
查看>>
mysql的分区和分表
查看>>
Java 读取 .properties 配置文件
查看>>
IntelliJ IDEA 12 key from twitter
查看>>
css
查看>>
装饰设计模式
查看>>
《Linux内核原理与分析》第八周作业
查看>>
企业级工作流解决方案(二)--微服务总体介绍
查看>>
Bonbo Git Server
查看>>
取消文件默认打开方式
查看>>
JVM 调试工具
查看>>
Linux C 语言 获取系统时间信息
查看>>
pku 1182 食物链
查看>>
echarts使用笔记四:双Y轴
查看>>
删除操作系统服务(Delete OS Service)
查看>>