`
wangzl2222
  • 浏览: 150887 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

Collections.unmodifiableList()

    博客分类:
  • java
阅读更多

在《重构——改善既有代码的设计》一书中,有一种重构手法叫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对象添加一个新课程。就好像,你必须让顾客自己向购物车里放食物,
而不能在顾客毫不知情下,偷偷向其购物车里放食物。

真是万物皆通情理啊:)

from:http://hi.baidu.com/onejava/blog/item/10388f2b77d340fae6cd4091.html

分享到:
评论
2 楼 奇林醉 2012-07-07  
有点明白了
1 楼 kensunhu 2011-04-18  
明白了Collections.unmodifiableList()的用意,谢谢!

相关推荐

    Java 实例 - 只读集合源代码+详细指导教程.zip

    例如,`Collections.unmodifiableList()`, `Collections.unmodifiableSet()`, 和 `Collections.unmodifiableMap()`分别用于创建只读列表、只读集合和只读映射。这些方法返回的集合在尝试进行添加、删除或替换元素...

    Collections

    * `Collections.unmodifiableList(List&lt;? extends T&gt; list)`: 返回一个不可变的列表。 示例代码 下面是一个使用 Collections 中部分方法的示例代码: ```java import java.util.ArrayList; import java.util....

    吐血推荐17个提升开发效率的“轮子”.doc

    List integers = Collections.unmodifiableList(list); integers.add(4); System.out.println(integers); 执行结果: UnsupportedOperationException 通过这些“轮子”,我们可以极大地提升我们的开发效率,提高...

    javaclooections类.docx

    - `Collections.unmodifiableList(List l)`: 将列表`l`包装为只读列表。 - `Collections.unmodifiableMap(Map m)`: 将映射`m`包装为只读映射。 - `Collections.unmodifiableSet(Set s)`: 将集合`s`包装为只读集合。 ...

    java collections design.pdf

    3. 包装器实现:如Collections工具类提供的不可变版本(如Collections.unmodifiableList()),以及同步集合(如Collections.synchronizedList())。 4. 抽象实现:如AbstractList、AbstractSet和AbstractMap,提供...

    commons-collections-3.2.1.jar

    List&lt;String&gt; unmodifiableList = CollectionUtils.unmodifiableList(new ArrayList()); // 使用过滤迭代器只保留偶数 List&lt;Integer&gt; numbers = Arrays.asList(1, 2, 3, 4, 5); Iterator&lt;Integer&gt; evenNumbers = ...

    ATA Java web应用开发模拟题B

    题目中展示了`Collections.unmodifiableList()`方法的使用,该方法返回一个只读视图,即一个不可变的列表。当尝试修改这个不可变列表时,会抛出`UnsupportedOperationException`异常,这在题目的第一部分得到了体现...

    关于 Java Collections API 您不知道的 5 件事,第 1 部分

    除了以上五点,还有一些实用的工具类,如`Collections.synchronizedList()`用于同步列表,`Collections.unmodifiableList()`创建只读列表,以及`Collections.reverse()`用于反转列表等。了解并善用这些特性,可以...

    Apache Commons Collections

    1. **集合增强**: Commons Collections提供了一系列接口和类,如`TransformedList`和`UnmodifiableList`,它们分别用于在操作列表时进行动态转换和防止修改。这些工具类可以帮助我们构建更安全、更具定制性的集合。...

    Java 实例 - 集合反转源代码-详细教程.zip

    但是,如果集合是不可变的,如`Collections.unmodifiableList()`返回的列表,尝试反转会抛出`UnsupportedOperationException`。 7. **扩展应用**: 反转操作在多种场景下都很有用,如实现堆栈(LIFO,后进先出)的...

    高效安全的Immutable List好处.docx

    1. 使用 JDK 内置的 `Collections.unmodifiableList()` 方法:这个方法可以将任何现有的 List 转换成不可修改的视图。例如,创建一个包含三个元素的列表,然后尝试添加元素会导致 `UnsupportedOperationException`。...

    Java多线程安全集合

    List&lt;String&gt; unmodifiableList = Collections.unmodifiableList(new ArrayList()); // 在多线程环境中使用这些集合进行操作... } } ``` 理解并熟练运用这些线程安全集合是构建健壮、高性能的多线程Java应用...

    java-collections-framework1016

    - **不可变集合**:通过`Collections.unmodifiableList()`等方法可以创建不可变集合,确保集合内容不会被意外修改。 - **泛型类型安全性**:自Java 5起,通过泛型机制增强了类型安全性,但需要注意避免在运行时发生...

    pef-utils-1.2.0.zip

    比如,通过使用`FastList`和`UnmodifiableList`等定制的集合实现,来替代标准的`ArrayList`和`Collections.unmodifiableList()`,在某些场景下能显著提升性能。 3. **并发支持**: 在并发编程中,GS Collections...

    Google-Guava-Collections-使用介绍

    传统的不可变集合通常是通过 `Collections.unmodifiableList()` 或类似方法创建的代理对象,这种对象只提供了一层简单的包装,实际上集合本身仍然是可变的。而 Guava 提供的 `ImmutableCollections` 真正实现了不可...

    【面试资料】-(机构内训资料)集合框架面试.zip

    9. 集合框架的不可变性:`Collections.unmodifiableList()`、`Collections.unmodifiableSet()`和`Collections.unmodifiableMap()`等方法创建只读视图,防止修改原始集合。 10. 泛型与类型安全:理解泛型的概念,...

    findbugs:may expose internal representation by returning

    4. **使用`Collections.unmodifiable*`**:对于集合类,可以返回`Collections.unmodifiableList()`、`Collections.unmodifiableSet()`等包装后的集合,防止外部修改。 5. **使用`final`关键字**:如果内部表示是...

    深入探索Java集合框架:解密复杂的面试题和精准解析

    - 使用Collections.unmodifiableList()等方法将可变集合转换为不可变集合。 15. **自定义迭代器** - 实现Iterator接口,重写hasNext()和next()方法,管理迭代状态和索引。 通过理解这些核心概念和差异,你将能够...

    Java面试问题2023集合

    12. **不可变集合**:`Collections.unmodifiableList()`、`Collections.unmodifiableSet()`和`Collections.unmodifiableMap()`等方法创建不可变集合,防止集合内容被修改,提高代码安全性。 13. **枚举Set**:`...

Global site tag (gtag.js) - Google Analytics