今天閱讀源碼的時候,無意中看到了Collections.unmodifiableList的用法,因為以前沒有這樣做過,所以查詢了他的API,是這樣寫的
public static <T> List<T> unmodifiableList(List<? extends T> list)
參數:list--這是一個不可修改視圖是要返回的列表中。
返回值:在方法調用返回指定列表的不可修改視圖。
1、用法探討:
1 public class CollectionsListDemo {
2 public static void main(String[] args) {
3
4 List<String> list = new ArrayList<String>();
5 list.add("aa");
6 list.add("bb");
7
8 System.out.println("初始化前: "+ list);
9
10 //實現 unmodifiable
11 List<Character> immutablelist = Collections.unmodifiableList(list);
12
13 //修改 list
14 immutablelist.add("zz");
15 }}
16
17 結果:
18
19 初始化前:: [aa, bb]
20
21 Exception in thread "main" java.lang.UnsupportedOperationException
2、繼續追蹤,到底什么場景遇到呢?重構是怎么寫的的?
在《重構——改善既有代碼的設計》一書中,有一種重構手法叫Encapsulate Collection ,(封裝集合),
定義是:讓函數返回這個集合的副本,并在這個類中提供添加/移除集合的副本
為了演示該重構手法
這本書介紹的是:我們經常用集合,Collection,可能是Array,ArrayList,set,vector保存一組實例,這樣的類通常也會提供針對該集合的取值與設值函數
但是集合的處理方式和其他種類略有不同,取值函數不應該返回集合本身,因為這會讓用戶得以修改集合的內容而集合擁有者去一無所知,這樣會對用戶 暴露過多的對象的內部結構信息。如果一個取值函數確實要返回多個值,他應該避免用戶直接操作對象內保存的集合,并隱藏對象內與用戶無關的的數據結構
此外,不應該為這個集合提供一個設置函數,但是應該提供對象內集合本身添加/刪除的函數,這樣,集合擁有者(對象)就可以控制集合元素的添加與刪除
如果做到了上邊的一點,集合就很好的封裝起來,這樣就降低了集合擁有者和用戶之間的耦合度
常用到的做法:
(1)加入為集合添加/移除元素的函數
(2)將保存的集合的字段初始化一個空的集合
3、下面對上邊的內容的例子介紹:
原來我這樣寫的:
1 import java.util.List;
2
3 public class Student
4 {
5 private String userName ;
6
7 private List<String> courses ;
8
9
10 public Student (String userName , List<String> courses)
11 {
12 this.userName = userName;
13 this.courses = courses;
14 }
15
16 public String getUserName()
17 {
18 return userName ;
19 }
20
21 public void setUserName(String userName)
22 {
23 this.userName = userName;
24 }
25
26 public List<String> getCourses()
27 {
28 return courses ;
29 }
30
31 public void setCourses(List<String> courses)
32 {
33 this.courses = courses;
34 }
35
36
37
38 }
重構后,按照上面介紹的原則,這樣重構:
1 import java.util.ArrayList;
2 import java.util.Collections;
3 import java.util.List;
4
5 public class Student
6 {
7 private String userName ;
8
9 private List<String> courses ;
10
11 public Student (String userName , List<String> courses)
12 {
13 this.userName = userName;
14 this.courses = courses;
15 }
16
17 public String getUserName()
18 {
19 return userName ;
20 }
21
22 public void setUserName(String userName)
23 {
24 this.userName = userName;
25 }
26
27 public void addCourse(String course)
28 {
29 courses.add(course);
30 }
31
32 public boolean removeCourse(String course)
33 {
34 return courses .remove(courses );
35
36 }
37
38 public List<String> getCourses()
39 {
40 return Collections.unmodifiableList( courses);
41 }
42
43 public static void main(String[] args)
44 {
45 List<String> list = new ArrayList<String>();
46 list.add( "數學");
47 list.add( "語文");
48 Student s = new Student("lily" , list);
49
50 List<String> anotherList = s.getCourses();
51
52 /**
53 * throws java.lang.UnsupportedOperationException should replace with
54 * s.addCourse(String course)
55 */
56 anotherList.add( "英語");
57
58 // 不會走到這一步,因為上邊拋出了異常
59 System. out.println("lily's course.length = " + s.getCourses().size());
60 }
61
62 }
4、總結
使用這種方法重構的意義:就好比我們網上購物一樣,你可以往購物車添加自己想買的東西,但是商戶不能在不通知顧客(我們)的情況下,就任意的添加商品,并修改商品的價格等,入口只能是一個,也就是在顧客手中。比喻可能不是很恰當,反正意思大概就是這樣。
文章列表