所有設計模式傳送門
迭代器模式:提供一種方法順序訪問一個集合對象中的各個元素,而又不需要暴漏對象的內部表示。
合理組織數據的結構以及相關操作時程序設計的一個重要方面,比如在程序設計中經常會使用諸如鏈表、散列表等數據結構。鏈表和散列表等數據結構都是可以存放若干個對象的集合,其區別時按着不同的方式來存儲對象。我們希望無論何種集合,應當允許程序以一種統一的方式遍歷集合中的對象,而不需要知道這些對象在集合中時如何表示存儲的。
迭代器模式是遍歷集合的一種成熟模式,迭代器模式的關鍵是將遍歷集合的任務交給一個稱作迭代器的對象。
包含角色:
1、集合(Aggregate):一個接口,規定了集合需要實現的操作。
2、具體集合(ConcreteArrregate):具體集合是實現集合接口的類的實例,具體集合按着一定的結構存儲對象,具體集合應當有一個方法,該方法返回一個針對該集合的具體迭代器。
3、迭代器(Iterator): 一個接口,規定了遍歷具體集合的方法,比如next()方法。
4、具體迭代器(ConcreteIterator): 實現集合接口的類的實例。具體迭代器在實現迭代器 接口所規定的遍歷集合的方法時,比如next()方法,要保證next()方法的首次調用將按着集合 的數據結構找到該集合中的一個對象,而且每當找到集合中的一個對象,立刻根據該集合的存儲結構得到待遍歷的後繼對象的引用,並保證依次調用next()方法可以遍歷集合。
優點:
1、用戶使用迭代器訪問集合中的對象,而不需要知道這些對象在集合中時如何表示以及存儲的。
2、用戶可以同時使用多個迭代器遍歷一個集合。
適用情景:
1、讓用戶訪問一個集合中的對象,但不想暴露對象在集合中的存儲結構。
2、希望對遍歷不同的集合提供一個統一的接口。
簡單的例子:現在有若干個學生,有姓名、學號和出生日期等屬性。
(1) 使用鏈表存放學生對象。
(2) 用一個散列表和一個樹集存放鏈表中的對象。
(3) 使用散列表查詢某個學生。
(4) 通過樹集將學生按成績排序。
設計實現:這裏設計三個類。其中UseSet類包含鏈表、散列表和樹集。Application負責創建Student的實例,並添加到UseSet所包含的集合中,UseSet提供了按Student的number屬性查找
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();
}
}
運行結果: