文章内容
一、什么是迭代器模式
迭代器模式,提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部细节。
迭代器模式,也叫游标模式,属于行为型设计模式。
二、迭代器模式类图
三、迭代器模式角色
- 迭代器角色(Iterator): 定义按顺序逐个遍历元素的接口,主要有hasNext和next两个方法。
- 具体迭代器角色(ConcreteIterator): 实现Iterator接口,实现对聚合对象的遍历,并记录当前游标的索引位置。
- 聚合角色(Aggregate):定义创建Iterator角色的接口,提供获取聚合对象的方法,还有添加元素、删除元素等方法。
- 具体聚合角色(ConcreteAggregate):实现Aggregate接口,它会创建出具体的Iterator角色,实现获取聚合对象的方法、添加元素、删除元素等方法。
四、迭代器模式优缺点
优点:
- 支持以不同的方式遍历一个聚合对象。
- 简化了聚合的接口,通过迭代器来遍历聚合对象。
- 在同一个聚合上可以有多个遍历。
缺点:
- 以复杂的方式同时遍历两个不同的数据结构时,迭代器实际上可能会成为累赘。
- 增加新的聚合类就需要增加新的迭代器类,类的个数成对增加,一定程度上增加到了系统维护的复杂性。
- 对于比较简单的遍历,使用迭代器模式显得较为繁琐。
五、迭代器模式demo示例
1、Demo需求
使用迭代器模式定义一个迭代器,迭代器元素定义为泛型,存储元素的集合使用List。例如:使用书本类(书名及价格)作为迭代器元素,聚合类含有添加元素、删除元素方法,并返回迭代器对象。最后使用迭代器对List集合进行遍历。
2、接口定义
/**
* 抽象迭代器角色:迭代器接口
*/ public interface Iterator<E> {
/**
* 是否有下一个元素
* @return
*/ boolean hasNext();
/**
* 获取下一个元素
* @return
*/ E next();
/**
* 获取第一个元素
* @return
*/ E first();
/**
* 获取最后一个元素
* @return
*/ E last();
}
/**
* 抽象聚合角色:聚合接口
*/ public interface Aggregate<E> {
/**
* 向集合中添加一个元素
* @param e
*/ void add(E e);
/**
* 从集合中删除一个元素
* @param e
*/ void remove(E e);
/**
* 返回一个迭代器对象
* @return
*/ Iterator<E> createMyIterator();
}
3、实现类定义
/**
* @Description: 具体迭代器角色:数组迭代器
**/ public class MyIterator<E> implements Iterator<E> {
// 存放对象的数组
private List<E> list;
// 当前索引所在的下标位置
private int position = 0;
/**
* 初始化list集合数据
* @param list
*/ public MyIterator(List<E> list) {
this.list = list;
}
/**
* 判断是否有下一个元素
* @return
*/ @Override
public boolean hasNext() {
return list.size() > position;
}
/**
* 获取下一个元素对象
* @return
*/ @Override
public E next() {
E e = list.get(position);
position++;
return e;
}
/**
* 获取第一个元素对象
* @return
*/ @Override
public E first() {
return list.get(0);
}
/**
* 获取最后一个元素对象
* @return
*/ @Override
public E last() {
if (list.size() == 0) {
return null;
}
return list.get(list.size() - 1);
}
}
/**
* @Description: 具体聚合角色:实现聚合功能(添加元素、删除元素、返回迭代器对象等)
**/ public class MyAggregate<E> implements Aggregate<E> {
// 集合对象
private List<E> list = new ArrayList<>();
/**
* 添加元素
* @param e
*/ @Override
public void add(E e) {
list.add(e);
}
/**
* 删除元素
* @param e
*/ @Override
public void remove(E e) {
list.remove(e);
}
/**
* 返回一个迭代器对象
* @return
*/ @Override
public Iterator<E> createMyIterator() {
return new MyIterator<>(list);
}
}
/**
* @Description: 书本类,充当元素对象
**/ public class Book {
private String name;
private Double price;
public Book(String name, Double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + ''' +
", price=" + price +
'}';
}
}
4、测试
/**
* @Description: 迭代器模式客户端测试类
**/ public class Client {
public static void main(String[] args) {
//构建聚合对象
Aggregate<Book> aggregate = new MyAggregate<>();
//添加书本对象
aggregate.add(new Book("计算机基础",80.00));
aggregate.add(new Book("java编程",60.00));
aggregate.add(new Book("python入门",50.00));
aggregate.add(new Book("PHP从入门到放弃",30.00));
//获取迭代器对象
Iterator<Book> iterator = aggregate.createMyIterator();
//打印第一本书
System.out.println("打印第一本书: "+iterator.first());
//打印最后一本书
System.out.println("打印最后一本书: "+iterator.last());
// 循环打印书本信息
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
控制台日志:
打印第一本书: Book{name='计算机基础', price=80.0}
打印最后一本书: Book{name='PHP从入门到放弃', price=30.0}
Book{name='计算机基础', price=80.0}
Book{name='java编程', price=60.0}
Book{name='python入门', price=50.0}
Book{name='PHP从入门到放弃', price=30.0}