Java設計模式之迭代器模式(五)
迭代器模式:提供一種方法順序訪問一個集合物件中的各個元素,而又不需要暴漏物件的內部表示。
合理組織資料的結構以及相關操作時程式設計的一個重要方面,比如在程式設計中經常會使用諸如連結串列、散列表等資料結構。連結串列和散列表等資料結構都是可以存放若干個物件的集合,其區別時按著不同的方式來儲存物件。我們希望無論何種集合,應當允許程式以一種統一的方式遍歷集合中的物件,而不需要知道這些物件在集合中時如何表示儲存的。
迭代器模式是遍歷集合的一種成熟模式,迭代器模式的關鍵是將遍歷集合的任務交給一個稱作迭代器的物件。
包含角色:
1、集合(Aggregate):一個介面,規定了集合需要實現的操作。
2、具體集合(ConcreteArrregate):具體集合是實現集合介面的類的例項,具體集合按著一定的結構儲存物件,具體集合應當有一個方法,該方法返回一個針對該集合的具體迭代器。
3、迭代器(Iterator): 一個介面,規定了遍歷具體集合的方法,比如next()方法。
4、具體迭代器(ConcreteIterator): 實現集合介面的類的例項。具體迭代器在實現迭代器 介面所規定的遍歷集合的方法時,比如next()方法,要保證next()方法的首次呼叫將按著集合 的資料結構找到該集合中的一個物件,而且每當找到集合中的一個物件,立刻根據該集合的儲存結構得到待遍歷的後繼物件的引用,並保證依次呼叫next()方法可以遍歷集合。
優點:
1、使用者使用迭代器訪問集合中的物件,而不需要知道這些物件在集合中時如何表示以及儲存的。
2、使用者可以同時使用多個迭代器遍歷一個集合。
適用情景:
1、讓使用者訪問一個集合中的物件,但不想暴露物件在集合中的儲存結構。
2、希望對遍歷不同的集合提供一個統一的介面。
簡單的例子:現在有若干個學生,有姓名、學號和出生日期等屬性。
(1) 使用連結串列存放學生物件。
(2) 用一個散列表和一個樹集存放連結串列中的物件。
(3) 使用散列表查詢某個學生。
(4) 通過樹集將學生按成績排序。
設計實現
Student例項方法,也提供了按score屬性進行排序的方法。
public class Student implements Comparable<Object>{ String number; String name; double score = 0; public Student() {} public Student(String number, String name, double score) { this.number = number; this.name = name; this.score = score; } public int compareTo(Object b) { Student st = (Student) b; if (Math.abs(this.score-st.score) <= 1/10000) return 1; return (int)(1000 * (this.score - st.score)); } public String getNumber() { return number; } public String getName() { return name; } public double getScore() { return score; } } public class UseSet { LinkedList<Student> list; Hashtable<String, Student> table; TreeSet<Student> tree; public UseSet(){ list = new LinkedList<Student>(); table = new Hashtable<String, Student>(); tree = new TreeSet<Student>(); } public void addStudent(Student stu) { list.add(stu); update(); } public void findStudent(String num) { Student stu = table.get(num); String number = stu.getNumber(); String name = stu.getName(); double score = stu.getScore(); System.out.println("學號:" + number + "姓名:" + name + "分數:" + score); } public void printStudentByScore() { Iterator<Student> iterator = tree.iterator(); while(iterator.hasNext()) { Student student = iterator.next(); String number = student.getNumber(); String name = student.getName(); double score = student.getScore(); System.out.println("學號:" + number + "姓名:" + name + "分數:" + score); } } private void update() { tree.clear(); Iterator<Student> iterator = list.iterator(); while(iterator.hasNext()) { Student student = iterator.next(); String number = student.getNumber(); table.put(number, student); tree.add(student); } } } public class Application { public static void main(String[] args) { UseSet useSet = new UseSet(); useSet.addStudent(new Student("001", "雷霆", 78.89)); useSet.addStudent(new Student("002", "火箭", 95.53)); useSet.addStudent(new Student("003", "勇士", 68.12)); useSet.addStudent(new Student("004", "騎士", 81.25)); useSet.addStudent(new Student("005", "灰熊", 74.32)); useSet.addStudent(new Student("006", "馬刺", 87.23)); useSet.addStudent(new Student("007", "湖人", 71.96)); String n = "003"; System.out.println("查詢學號為"+n+"的學生:"); useSet.findStudent(n); System.out.println("將學生按成績排列:"); useSet.printStudentByScore(); } }
執行結果: