迭代器模式介绍
一个集合对象,如List,要提供一个访问它元素的方法,前提是不暴露它的内部结构。此外,你可能根据不同的场景对集合对象选择不同的遍历方法,你不想把遍历逻辑放在对象集合中,这样会增加集合对象的复杂度,你甚至在某个场景下对同一个集合对象进行多次遍历。带着这些前提条件该如何实现集合对象的遍历呢?
迭代器模式可以解决上面提出的问题,它的核心思想是提供一个额外的对象负责访问和遍历集合对象。 Iterator
是一个接口负责访问集合的元素,迭代器对象负责记录集合被遍历的当前元素,也就是说它知道集合里的哪些元素已被遍历。
迭代器模式详解
迭代器模式的目的是提供一个不暴露集合内部结构的访问集合元素的方法。迭代器设计符合OOP的单一职责。
** Iterator **
- 访问和遍历集合元素的接口
** ConcreteIterator **
- 实现接口
Iterator
- 记录集合被遍历的当前位置
** Aggregate **
- 用来创建
Iterator
对象的接口
** ConcreateAggregate **
- 实现接口
Aggregate
, 返回ConcreteIterator
对象
代码实现
定义一个类 Shape
, 代表正方形、长方形、圆形等形状。类 ShapeStorage
是 Shape 的集合,类 IteratorShape
用来遍历 Shape的集合。
public class Shape {
private int id;
private String name;
public Shape(int id, String name) {
this.id = id;
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Shape{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
public class ShapeIterator implements Iterator<Shape> {
private final Shape[] shapes;
private int position;
public ShapeIterator(Shape[] shapes) {
this.shapes = shapes;
}
@Override
public boolean hasNext() {
return position <= shapes.length - 1 && shapes[position] != null;
}
@Override
public Shape next() {
return shapes[position++];
}
@Override
public void remove() {
if (position <= 0) {
throw new IllegalArgumentException("Illegal position");
}
for (int i = position - 1; i < shapes.length - 1; i++) {
shapes[i] = shapes[i + 1];
}
shapes[shapes.length - 1] = null;
}
}
public class ShapeStorage {
private final Shape[] shapes = new Shape[5];
private int index;
public void addShape(String name){
int i = index++;
shapes[i]= new Shape(i,name);
}
public Shape[] getShapes(){
return shapes;
}
}
public class TestIteratorPattern {
public static void main(String[] args) {
ShapeStorage storage = new ShapeStorage();
storage.addShape("Polygon");
storage.addShape("Hexagon");
storage.addShape("Circle");
storage.addShape("Rectangle");
storage.addShape("Square");
ShapeIterator iterator = new ShapeIterator(storage.getShapes());
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println("Apply removing while iterating...");
iterator = new ShapeIterator(storage.getShapes());
while (iterator.hasNext()) {
System.out.println(iterator.next());
iterator.remove();
}
}
}
输出结果:
Shape{id=0, name=‘Polygon’}
Shape{id=1, name=‘Hexagon’}
Shape{id=2, name=‘Circle’}
Shape{id=3, name=‘Rectangle’}
Shape{id=4, name=‘Square’}
Apply removing while iterating…
Shape{id=0, name=‘Polygon’}
Shape{id=2, name=‘Circle’}
Shape{id=4, name=‘Square’}
使用迭代器模式的场景
- 访问集合元素但不暴露内部的结构
- 支持对集合对象的多种遍历方式
- 提供一个统一的接口遍历不同的集合
Jdk 内部使用迭代器模式的例子
- java.util.Iterator
- java.util.Enumeration