所有设计模式传送门
迭代器模式:提供一种方法顺序访问一个集合对象中的各个元素,而又不需要暴漏对象的内部表示。
合理组织数据的结构以及相关操作时程序设计的一个重要方面,比如在程序设计中经常会使用诸如链表、散列表等数据结构。链表和散列表等数据结构都是可以存放若干个对象的集合,其区别时按着不同的方式来存储对象。我们希望无论何种集合,应当允许程序以一种统一的方式遍历集合中的对象,而不需要知道这些对象在集合中时如何表示存储的。
迭代器模式是遍历集合的一种成熟模式,迭代器模式的关键是将遍历集合的任务交给一个称作迭代器的对象。
包含角色:
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();
}
}
运行结果: