• Collections.unmodifiableList方法的使用与场景


    转载:https://blog.csdn.net/cilen/article/details/7744969

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

    真是万物皆通情理啊:)

  • 相关阅读:
    【java】jfairy和java-faker假数据利器
    【Spring boot】【gradle】idea新建spring boot+gradle项目
    【mac】mac上使用brew 安装速度慢/每次使用brew 都会卡在updating homebrew不动/更换homebrew的镜像源
    【gradle】mac上安装gradle
    【mac】mac上安装JDK
    如何解决ajax跨域问题(转)
    java实现点选汉字验证码(自己修改后的)
    AES加解密
    java随机打乱集合顺序
    利用StringEscapeUtils对字符串进行各种转义与反转义(Java)
  • 原文地址:https://www.cnblogs.com/mybatis/p/9336506.html
Copyright © 2020-2023  润新知