该文章是阅读《图解设计模式》的学习笔记。书本链接https://www.ituring.com.cn/book/1811
假如现在要求从一堆Student对象实例中,找到名称为"test5"的学生信息并输出其信息。本人首先想到的是直接使用for循环即可解决问题,下面来看假如直接使用for循环会有什么不足之处。
import java.util.ArrayList;
import java.util.List;
public class Student {
private int num;
private String name;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student(int num, String name) {
this.num = num;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"num=" + num +
", name='" + name + '\'' +
'}';
}
public static void main(String[] args) {
Student[] students=new Student[10];
List<Student> studentList = new ArrayList<Student>();
for(int i=0;i<10;i++){
students[i]=new Student(i,"test"+i);
studentList.add(i,new Student(i,"test"+i));
}
//要求输出姓名为test5的学生信息
for(Student student:students){
if("test5".equals(student.name)){
System.out.println(student);
}
}
for(Student student:studentList){
if("test5".equals(student.name)){
System.out.println(student);
}
}
}
}
从代码中可以看出无论是使用数组还是List列表集合,只要使用了for循环,遍历和实现就没法分离开。即对象数组与for循环内部的实现操作无法进行分离。显然,如果遍历和实现分离了的话,无论使用何种数据结构存储这一堆Student对象数据,都不会影响到使用这一堆数据进行实现操作的人。因此,就需要用到Iterator模式。先来看一些这些类之间的关系。主要使用到集合类、迭代器类、具体的对象类、具体的集合类和具体的迭代器类这五个类:
上图中,空心三角形的虚线实现关系,方向是子类指向父类;如果是空心三角形实线表示继承关系,方向是实现指向被实现;带菱形的箭头表示聚合关系,方向是由包含者指向被包含者;普通实线箭头表示关联关系,如上图的关联关系是指通过Gather集合创建迭代器。
下面我们看一下代码:
Gather集合类代码:
public interface Gather {
public abstract Iterators iterator();
}
Iterators迭代器类代码:
public interface Iterators {
public abstract boolean hasNext();
public abstract Object next();
}
Student对象类代码:
public class Student {
private int num;
private String name;
@Override
public String toString() {
return "Student{" +
"num=" + num +
", name='" + name + '\'' +
'}';
}
public Student(int num, String name) {
this.num = num;
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
StudentGather具体集合类代码:
import java.util.ArrayList;
import java.util.List;
public class StudentGather implements Gather {
private List<Student> studentList;
private int total = 0;
public StudentGather() {
this.studentList = new ArrayList<Student>();
}
public Student getStudentAt(int index){
return studentList.get(index);
}
public void addStudent(Student student){
this.studentList.add(student);
total++;
}
public long getTotal(){
return total;
}
@Override
public Iterators iterator() {
return new StudentIterator(this);
}
}
StudentIterator具体迭代器类代码:
public class StudentIterators implements Iterators {
private StudentGather studentGather;
private int index;
public StudentIterators(StudentGather studentGather) {
this.studentGather = studentGather;
this.index = 0;
}
@Override
public boolean hasNext() {
if(index<studentGather.getTotal())
return true;
return false;
}
@Override
public Object next() {
Student student = studentGather.getStudentAt(index);
index++;
return student;
}
}
Main类代码:
public class Main {
public static void main(String[] args) {
StudentGather studentGather = new StudentGather();
studentGather.addStudent(new Student(0,"test0"));
studentGather.addStudent(new Student(1,"test1"));
studentGather.addStudent(new Student(2,"test2"));
studentGather.addStudent(new Student(3,"test3"));
studentGather.addStudent(new Student(4,"test4"));
studentGather.addStudent(new Student(5,"test5"));
Iterators iterators = studentGather.iterator();
while (iterators.hasNext()){
Student student = (Student)iterators.next();
if("test5".equals(student.getName())){
System.out.println(student);
}
}
}
}
使用了Iterator设计模式后,就可以将遍历和实现分离,在实现的使用使用了iterator进行遍历操作,与studentGather这一对象集合分离了。
分析里面包含的类角色:
集合类(Gather):声明了Iterators这个抽象方法,用于创建Iterators这个迭代器类角色。
迭代器类(Iterators):声明了hasNext和next两个抽象方法,用于实现对Gather集合数据进行遍历。
具体的迭代器类(StudentIterators):用于实现迭代器里面的遍历方法。
具体的集合类(StudentGather):用于实现集合类的接口,创建出包含具体数据的Iterators角色对象。