17、迭代器模式
**迭代器模式(Iterator):**提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
在容器里存放了大量的同类型对象,我们如果想逐个访问容器中的对象,就必须要知道容器的结构。比如,ArrayList 和 LinkedList 的遍历方法一定是不一样的,这对于容器的使用者而言,肯定是一个巨大的负担。作为容器的使用者,我肯定希望所有的容器能提供一个统一的接口,这个接口可以遍历容器中的所有内容,又可以把容器的细节屏蔽掉。
确实存在这样的一个统一的接口,这个接口就是 java.util.Iterator。先看类图,下面的这幅图所表示的意思就是,在一个容器类上实现createIterator方法,这个方法可以创建一个迭代器,使用这个迭代器就可以遍历容器中的所有元素了。
UML类图:
抽象容器角色(Aggregate):负责提供创建具体迭代器角色的接口,一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
具体容器角色(ConcreteAggregate):就是实现抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkedList,Set接口的哈希列表的实现HashSet等。
抽象迭代器角色(Iterator):负责定义访问和遍历元素的接口。
具体迭代器角色(ConcreteIterator):实现迭代器接口,并要记录遍历中的当前位置。
具体案例:每个学校有不同院系,每个院系有不同专业,使用迭代器按顺序访问学校不同院系以及院系的不同专业。
具体案例UML类图:
Java代码:
// 我的迭代器
public interface MyIterator<E> {
boolean hasNext();
E next();
}
// 计算机学院迭代器
public class ComputerIterator<E> implements MyIterator {
private E[] majors;
private int size;
private int index;
public ComputerIterator(E[] majors, int size) {
this.majors = majors;
this.size = size;
this.index = 0;
}
@Override
public boolean hasNext() {
if(index>=size){
return false;
}
return true;
}
@Override
public E next() {
return majors[index++] ;
}
}
// 金融学院迭代器
public class FinanceIterator<E> implements MyIterator {
private List<E> lists;
int index = -1;
public FinanceIterator(List<E> lists) {
this.lists = lists;
}
@Override
public boolean hasNext() {
if (index >= lists.size() - 1) {
return false;
}
index++;
return true;
}
@Override
public E next() {
return lists.get(index);
}
}
// 抽象的学院类
public abstract class Department {
protected String name;
public Department(String name) {
this.name = name;
}
public abstract MyIterator createIterator();
public abstract void add(Major major);
public String getName() {
return name;
}
}
// 计算机学院
public class ComputerDepartment extends Department {
private Major[] majors;
private int size;
public ComputerDepartment(String name) {
super(name);
majors = new Major[5];
size = 0;
}
public void add(Major major) {
majors[size] = major;
size++;
}
@Override
public MyIterator createIterator() {
return new ComputerIterator<Major>(majors, size);
}
}
// 金融学院
public class FinanceDepartment extends Department {
private ArrayList<Major> majors;
public FinanceDepartment(String name) {
super(name);
majors = new ArrayList<>();
}
public void add(Major major) {
majors.add(major);
}
@Override
public MyIterator createIterator() {
return new FinanceIterator<Major>(majors);
}
}
public class Test62 {
public static void main(String[] args) {
Department computerDepartment = new ComputerDepartment("计算机学院");
Department financeDepartment = new FinanceDepartment("金融学院");
Major computer = new Major("计算机专业");
Major software = new Major("软件专业");
Major economics = new Major("经济学专业");
Major investment = new Major("投资学专业");
computerDepartment.add(computer);
computerDepartment.add(software);
financeDepartment.add(economics);
financeDepartment.add(investment);
ArrayList<Department> departments = new ArrayList<>();
departments.add(computerDepartment);
departments.add(financeDepartment);
for (Department department : departments) {
System.out.println("===============" + department.getName() + "=================");
MyIterator iterator = department.createIterator();
while (iterator.hasNext()) {
Major major = (Major) iterator.next();
System.out.println(major.getName());
}
}
}
}