酷爱生活、享受文娱、专注技术,欢迎关注QGer,我们1起见证成长!
甚么是迭代器模式?
官方解释:to access the elements of an aggregate object sequentially without exposing its underlying implementation.
顺序地访问集合对象的元素并且不暴露它的内部实现
通俗解释:假定给定1个集合对象,定义1个与之相干联的Iterator(迭代器),该迭代器能够访问集合对象的内部元素,通过迭代的方法能够依照顺序顺次访问集合对象的每个元素。
为何使用迭代器模式?
如何使用迭代器模式?
UML图以下:
各个组件解释:
Iterator:抽象迭代器,定义了迭代器最基本的接口。如:hasNext()表示是不是该迭代是不是还有下1个元素,next则是返回迭代的下1个元素。
Aggregate:抽象集合,定义了集合的基本操作接口。如:add()向该集合增加1个原色,remove()则表示删除某个元素。
ComcreteAggregate:具体数据集合类,定义了集合元素的结构,操作细节。同时在类内部定义了1个具体迭代器并提供1个能够返回迭代器对象的方法。
ConcreteIterator:具体迭代器,通常定义在聚合类的内部,以此来到达访问聚合类内部数据结构的目的,同时实现了迭代访问聚合类元素的方法。
使用范围:
当你想要在不暴露其内部表示的情况下访问1个对象集合
当你想要有多种遍历方式来遍历1个对象集合,如正序、倒序、跳表访问
利用举例:
假定现在有1个学生对象集合类,客户端其实不想关心其内部细节,只需要能遍历学生对象(或学生对象的某些属性)便可。使用迭代器模式来实现这个需求。
1、定义迭代器和集合的抽象接口。
interface Iterator<T> {
T next();
boolean hasNext();
}
interface Collection<T> {
boolean add(T element);
boolean remove(T element);
}
2、定义学生对象类,简明起见,不定义太多复杂属性
public class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
}
3、实现具体学生对象聚合类,并在内部依赖定义具体迭代器。
public class StudentList implements Collection<Student> {
List<Student> elementList = new ArrayList<>();
@Override
public void add(Student element) {
elementList.add(element);
}
@Override
public boolean remove(Student element) {
return elementList.remove(element);
}
public Iterator<Student> createIterator(){
return new StudentIterator(elementList);
}
//具体迭代器类
private class StudentIterator implements Iterator<Student> {
private List<Student> students;
private int position;
public StudentIterator(List<Student> students) {
this.students = students;
this.position = 0;
}
@Override
public Student next() {
if(hasNext()) {
return students.get(position++);
}
return null;
}
@Override
public boolean hasNext() {
return position < students.size();
}
}
}
4、使用客户端调用,此处mock1个测试数据,方便调用。
public class Client {
public static void main(String[] args) {
StudentList studentList = new StudentList();
studentList.add(new Student("001", "张3"));
studentList.add(new Student("002", "李4"));
studentList.add(new Student("004", "赵5"));
studentList.add(new Student("004", "钱6"));
Iterator<Student> iterator = studentList.createIterator();
while(iterator.hasNext()){
Student student = iterator.next();
System.out.println(student.getId() + student.getName());
}
}
}
注:此处的抽象迭代器、抽象集合接口,均只声明了最简单经常使用的方法,之际开发中可以根据需求增加各种各样的方法,如Java.Util里面的Iterator定义接口以下:
迭代器则可以根据具体的聚合,选择不同的遍历方式:正序、倒序、跳表等。而遍历的可以不是全部对象,也许你指向遍历对象的某个属性呢,如上例你指向要遍历学生的学号,或说学号用得最勤劳,那末你另外定义1个迭代方法nextId来遍历学生的学号呀。