思考迭代器模式
迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即不暴露其内部的结构。
1.迭代器模式的本质
迭代器模式的本质:控制访问聚合对象中的元素。
迭代器模式(Iterator Pattern)是一种行为设计模式,它用于提供一种统一的方式来遍历集合对象中的元素,而无需暴露集合的内部表示方式。该模式将遍历操作封装在一个独立的迭代器对象中,使得可以对集合进行迭代而不暴露其底层结构。
通过封装、隔离和统一接口,迭代器模式实现了对集合的遍历行为的灵活性和扩展性。它使得客户端代码与具体集合实现解耦,提高了代码的可维护性和可复用性。
2.何时选用迭代器模式
建议在以下情况中选用迭代器模式。
-
需要遍历集合对象:当需要遍历一个集合对象并访问其中的元素时,可以使用迭代器模式。它提供了一种统一的方式来遍历集合,而无需关心集合的具体实现。
-
需要隐藏集合的内部结构:如果希望对外部代码隐藏集合对象的内部结构,只暴露一组统一的遍历接口,那么可以使用迭代器模式。迭代器将遍历逻辑封装在迭代器对象中,使得客户端无法直接访问集合的元素,从而保护了集合的完整性和安全性。
-
需要支持多种遍历方式:迭代器模式可以实现不同的迭代器对象,每个迭代器对象都可以实现一种不同的遍历方式。这样,客户端可以根据需要选择不同的迭代器对象来遍历集合,而不需要修改客户端代码。
-
需要解耦集合和遍历逻辑:如果希望集合对象和遍历逻辑可以独立变化,互不影响,那么可以使用迭代器模式。迭代器模式将集合对象和遍历逻辑分离,它们之间通过迭代器接口进行交互,使得它们可以独立地进行修改和扩展。
3.优缺点
迭代器模式的优点。
-
分离集合与迭代逻辑:迭代器模式将集合对象与遍历逻辑分离,使得它们可以独立变化。集合对象只需要实现迭代器接口,而客户端只需要通过迭代器进行遍历操作,从而实现了解耦和模块化。
-
统一遍历接口:迭代器模式定义了一组统一的遍历接口,使得客户端可以以相同的方式对待不同类型的集合对象。无论是数组、链表、树状结构还是其他自定义集合,只要它们提供了符合迭代器接口的迭代器对象,就可以使用迭代器模式进行遍历,提高了代码的灵活性和可复用性。
-
简化客户端代码:使用迭代器模式可以简化客户端代码,减少了对集合内部结构的直接操作,只需要通过迭代器对象进行遍历操作。这样可以降低代码的复杂度,并且使客户端代码更加清晰、易于理解和维护。
4.迭代器模式的结构
- Iterator:迭代器接口。定义访问和遍历元素的接口。
- ConcreteIterator:具体的迭代器实现对象。实现对聚合对象的遍历,并跟踪遍历时的当前位置。
- Aggregate:聚合对象。定义创建相应迭代器对象的接口。
- ConcreteAggregate:具体聚合对象。实现创建相应的迭代器对象。
5.实现
手动实现迭代器模式
一个学院有多个系,计算机学院用数组存的,数学学院用集合存的,其他学院也是有的用数组存,有的用集合存,因为遍历集合和遍历数组的代码不同,遍历所有学院很困难,可以用迭代器模式实现这个效果
1.迭代器类
/**
* @description:自己实现的迭代器接口
*/
public interface MyIterator {
/**
* 移动到第一个元素
*/
void first();
/**
* 移动到下一个元素
*/
void next();
/**
* 判断是否是最后一个元素
* @return
*/
boolean isDone();
/**
* 获取当前元素
* @return
*/
Object currentItem();
}
/**
* @description:计算机学院迭代器
*/
public class ComputerIterator implements MyIterator{
/**
* 计算机学院对象
*/
private ComputerCollege computerCollege=null;
/**
* 记录索引位置
*/
private int index=-1;
public ComputerIterator(ComputerCollege computerCollege) {
this.computerCollege = computerCollege;
}
@Override
public void first() {
index=0;
}
@Override
public void next() {
if (index<this.computerCollege.size()){
index++;
}
}
@Override
public boolean isDone() {
if (index==this.computerCollege.size()){
return true;
}
return false;
}
@Override
public Object currentItem() {
return this.computerCollege.get(index);
}
}
/**
* @description:计算机学院迭代器
*/
public class MathIterator implements MyIterator{
private MathCollege mathCollege;
private int index=-1;
public MathIterator(MathCollege mathCollege) {
this.mathCollege = mathCollege;
}
@Override
public void first() {
index=0;
}
@Override
public void next() {
if (index<this.mathCollege.size()){
index++;
}
}
@Override
public boolean isDone() {
if (index==this.mathCollege.size()){
return true;
}
return false;
}
@Override
public Object currentItem() {
return this.mathCollege.get(index);
}
}
2.学院类
/**
* @description:学院接口
*/
public interface College {
/**
* 创建迭代器
* @return
*/
MyIterator createIterator();
}
/**
* @description:计算机学院类
*/
public class ComputerCollege implements College{
private Department[] departments=null;
@Override
public MyIterator createIterator() {
//初始化数据
departments=new Department[3];
departments[0]=new Department(1,"软件");
departments[1]=new Department(2,"通信");
departments[2]=new Department(3,"电子");
return new ComputerIterator(this);
}
/**
* 获取元素
* @param index
* @return
*/
public Object get(int index){
Object obj=null;
if (index<this.departments.length){
obj=departments[index];
}
return obj;
}
/**
* 返回学院下系的数量
* @return
*/
public int size(){
return this.departments.length;
}
}
/**
* @description:数学学院类
*/
public class MathCollege implements College{
private List<Department> departmentList=null;
@Override
public MyIterator createIterator() {
//初始化数据
departmentList=new ArrayList<>();
departmentList.add(new Department(1,"数学系"));
departmentList.add(new Department(2,"概率系"));
departmentList.add(new Department(3,"统计系"));
return new MathIterator(this);
}
/**
* 获取元素
* @param index
* @return
*/
public Object get(int index){
Object obj=null;
if (index<this.departmentList.size()){
obj=departmentList.get(index);
}
return obj;
}
/**
* 返回学院下系的数量
* @return
*/
public int size(){
return this.departmentList.size();
}
}
3.实体类
/**
* @description:系
*/
@Data
@AllArgsConstructor
public class Department {
/**
* 系id
*/
private Integer id;
/**
* 系名
*/
private String name;
}
4.测试类
/**
* @description:TODO
*/
public class Client {
public static void main(String[] args) {
//计算机学院
MyIterator citerator = new ComputerCollege().createIterator();
citerator.first();
while (!citerator.isDone()){
Object o = citerator.currentItem();
System.out.println(o);
citerator.next();
}
System.out.println("==========================================");
//数学学院
MyIterator miterator = new MathCollege().createIterator();
miterator.first();
while (!miterator.isDone()){
Object o = miterator.currentItem();
System.out.println(o);
miterator.next();
}
}
}
5.结果:
Department(id=1, name=软件)
Department(id=2, name=通信)
Department(id=3, name=电子)
==========================================
Department(id=1, name=数学系)
Department(id=2, name=概率系)
Department(id=3, name=统计系)
java迭代器模式
以计算机学院举例修改
1.修改学院接口,返回为java的Iterator对象
/**
* @description:学院接口
*/
public interface College {
/**
* 创建迭代器
* @return
*/
Iterator createIterator();
}
/**
* @description:计算机学院类
*/
public class ComputerCollege implements College {
private Department[] departments=null;
@Override
public Iterator createIterator() {
//初始化数据
departments=new Department[3];
departments[0]=new Department(1,"软件");
departments[1]=new Department(2,"通信");
departments[2]=new Department(3,"电子");
return new ComputerIterator(this);
}
/**
* 获取元素
* @param index
* @return
*/
public Object get(int index){
Object obj=null;
if (index<this.departments.length){
obj=departments[index];
}
return obj;
}
/**
* 返回学院下系的数量
* @return
*/
public int size(){
return this.departments.length;
}
}
2.迭代器类实现java的Iterator,重写方法
/**
* @description:计算机学院迭代器
*/
public class ComputerIterator implements Iterator {
/**
* 计算机学院对象
*/
private ComputerCollege computerCollege=null;
/**
* 记录索引位置
*/
private int index=0;
public ComputerIterator(ComputerCollege computerCollege) {
this.computerCollege = computerCollege;
}
@Override
public boolean hasNext() {
if(computerCollege!=null&&index<computerCollege.size()){
return true;
}
return false;
}
@Override
public Object next() {
Object obj=null;
if (hasNext()){
obj=computerCollege.get(index);
index++;
}
return obj;
}
}
3.测试,可以看到比自己手动实现简单一些
public class Client2 {
public static void main(String[] args) {
Iterator iterator = new ComputerCollege().createIterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
}
4.结果
Department(id=1, name=软件)
Department(id=2, name=通信)
Department(id=3, name=电子)